Instantly share code, notes, and snippets.
Last activeJuly 18, 2025 17:28
Save peter-b/1908406c6dd2d8d7f97cbd67e595d6d3 to your computer and use it in GitHub Desktop.
HMAC-SHA-1 password storage using LiveCode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
/* Compute a hash-based message authentication code | |
using the SHA-1 hash. This is broken; it should correctly | |
follow RFC 2104.*/ | |
privatefunctionhmacSha1 pKey, pMessage | |
returnsha1digest(pKey&sha1digest(pKey&pMessage)) | |
endhmacSha1 | |
/* Constant time string comparison algorithm. This | |
prevents against timing attacks on the hashed password | |
comparison.*/ | |
privatefunctionhashEqual pLeft, pRight | |
localtEqual,tIdx | |
puttrueintotEqual | |
setthe caseSensitivetotrue | |
-- Ensure comparison is performed and tEqual is assigned | |
-- for every character in pLeft | |
repeatwithtIdx=1tothenumberofcharsinpLeft | |
puttEqualand (chartIdxofpLeftischartIdxofpRight)intotEqual | |
end repeat | |
returntEqual | |
endhashEqual | |
/* Generate a 160-bit salt value suitable for use when | |
storing a password*/ | |
privatefunctiongenerateSalt | |
returnrandomBytes(20) | |
endgenerateSalt | |
/* 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.*/ | |
privatefunctionsecurePassword pPasswordString, pSaltData | |
localtPasswordData | |
puttextEncode(pPasswordString,"UTF-8")intotPasswordData | |
returnbase64Encode(pSaltData)&comma& \ | |
base64Encode(hmacSha1(pSaltData,tPasswordData)) | |
endsecurePassword | |
/* Get the salt part of a secured password string*/ | |
privatefunctiongetSecurePasswordSalt pSecurePassword | |
returnbase64Decode(item1ofpSecurePassword) | |
endgetSecurePasswordSalt | |
/* Store a new password. Use this when a user creates | |
a new account or changes their password for any reason*/ | |
functionstorePassword pPasswordString | |
return securePassword(pPasswordString, generateSalt()) | |
endstorePassword | |
/* Verify a password. Use this when a user tries to log | |
in. Returns true if the password is correct and false | |
otherwise.*/ | |
functionverifyPassword pPasswordString, pSecurePassword | |
localtSaltData,tTrialString | |
put getSecurePasswordSalt(pSecurePassword)intotSaltData | |
put securePassword(pPasswordString,tSaltData)intotTrialString | |
return hashEqual(tTrialString,pSecurePassword) | |
endverifyPassword | |
--------------------------------------------------------- | |
privatecommand_testAssert pDesc, pCondition | |
ifpConditionthen | |
put"ok -"&&pDesc& returnafter msg | |
else | |
put"not ok -"&&pDesc& returnafter msg | |
end if | |
end_testAssert | |
command_testPasswordDemo | |
localtSecured | |
put storePassword("correct horse battery staple")intotSecured | |
put"# Stored:"&&tSecured& returninto msg | |
_testAssert"bad password", \ | |
not verifyPassword("hunter2",tSecured) | |
_testAssert"good password", \ | |
verifyPassword("correct horse battery staple",tSecured) | |
end_testPasswordDemo |
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment