Skip to content

Instantly share code, notes, and snippets.

@peter-b
Last active March 28, 2017 13:23
Show Gist options
  • Save peter-b/1908406c6dd2d8d7f97cbd67e595d6d3 to your computer and use it in GitHub Desktop.
Save peter-b/1908406c6dd2d8d7f97cbd67e595d6d3 to your computer and use it in GitHub Desktop.
HMAC-SHA-1 password storage using LiveCode
/* Compute a hash-based message authentication code
using the SHA-1 hash. This is broken; it should correctly
follow RFC 2104. */
private function hmacSha1 pKey, pMessage
return sha1digest(pKey & sha1digest(pKey & pMessage))
end hmacSha1
/* Constant time string comparison algorithm. This
prevents against timing attacks on the hashed password
comparison. */
private function hashEqual pLeft, pRight
local tEqual, tIdx
put true into tEqual
set the caseSensitive to true
-- Ensure comparison is performed and tEqual is assigned
-- for every character in pLeft
repeat with tIdx = 1 to the number of chars in pLeft
put tEqual and (char tIdx of pLeft is char tIdx of pRight) into tEqual
end repeat
return tEqual
end hashEqual
/* Generate a 160-bit salt value suitable for use when
storing a password */
private function generateSalt
return randomBytes(20)
end generateSalt
/* Convert the specified cleartext password string to an
secure string suitable for storage using the specified
salt, which should be a base 64-encoded string. */
private function securePassword pPasswordString, pSaltData
local tPasswordData
put textEncode(pPasswordString, "UTF-8") into tPasswordData
return base64Encode(pSaltData) & comma & \
base64Encode(hmacSha1(pSaltData, tPasswordData))
end securePassword
/* Get the salt part of a secured password string */
private function getSecurePasswordSalt pSecurePassword
return base64Decode(item 1 of pSecurePassword)
end getSecurePasswordSalt
/* Store a new password. Use this when a user creates
a new account or changes their password for any reason */
function storePassword pPasswordString
return securePassword(pPasswordString, generateSalt())
end storePassword
/* Verify a password. Use this when a user tries to log
in. Returns true if the password is correct and false
otherwise. */
function verifyPassword pPasswordString, pSecurePassword
local tSaltData, tTrialString
put getSecurePasswordSalt(pSecurePassword) into tSaltData
put securePassword(pPasswordString, tSaltData) into tTrialString
return hashEqual(tTrialString, pSecurePassword)
end verifyPassword
---------------------------------------------------------
private command _testAssert pDesc, pCondition
if pCondition then
put "ok -" && pDesc & return after msg
else
put "not ok -" && pDesc & return after msg
end if
end _testAssert
command _testPasswordDemo
local tSecured
put storePassword("correct horse battery staple") into tSecured
put "# Stored:" && tSecured & return into msg
_testAssert "bad password", \
not verifyPassword("hunter2", tSecured)
_testAssert "good password", \
verifyPassword("correct horse battery staple", tSecured)
end _testPasswordDemo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment