Last active
March 28, 2017 13:23
-
-
Save peter-b/1908406c6dd2d8d7f97cbd67e595d6d3 to your computer and use it in GitHub Desktop.
HMAC-SHA-1 password storage using LiveCode
This file contains 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. */ | |
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