Created
June 9, 2021 21:14
-
-
Save orip/e26bef3aa0348bb7f454996d1144d552 to your computer and use it in GitHub Desktop.
Test vectors for iterated HMAC-SHA-256 used as a salted hash algorithm with CPU stretching
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
# Iterated HMAC-SHA-256 password hashing homebrew | |
# Important: avoid this. Use argon2 or scrypt instead (CPU+mem stretching) or PBKDF2 or bcrypt (just CPU) | |
def iterated_hmacsha256(password, salt, extra_rounds): | |
import hmac, hashlib | |
current = salt | |
for i in range(1 + extra_rounds): # extra rounds beyond the first | |
current = hmac.new(key=password, msg=current, digestmod=hashlib.sha256).digest() | |
return current | |
# These vectors have been verified with multiple implementations | |
test_vectors = [ | |
{"password": "very secret", "salt_hex": "33c177c69050b61066215084a34816ae", "extra_rounds": 321, "result_hex": "84b8be66436b9b5072df17e1dd216faef3d8460e25c2a3f659ac6aae6642a42e"}, | |
{"password": "very secret", "salt_hex": "33c177c69050b61066215084a34816ae", "extra_rounds": 10000, "result_hex": "2eb68f678bc1d5b4b3050b032e2cd2f9e7de9ed57232c312901813e70ec3a910"}, | |
{"password": "", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "8e111d21005bf86277073244e449309bb46571eb6c540320c18fea9c52cf9424"}, | |
{"password": "A", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "0248a03e7e3b85a9e60846c5c06b137a9c7291a4662e629e0c4d086e37b59350"}, | |
{"password": "As", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "67707f4c668f68a25aaff744cdfaae0a8806fd27722ef045d42865e8182ec0f4"}, | |
{"password": "As_", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "371b90c051e7e9086d89ed21b457ed9fe97e7701eca4e7348cb44df20eae0fe3"}, | |
{"password": "As_c", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "eb14fd73ad2e747a8746e0644a02ca71b9bf73a0222a7c9a4f1d6ce86bfa1694"}, | |
{"password": "As_c]", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "e004cbe22f44b6eb543e784b846815213cd3d31809a506e2c944a7fedc8ac773"}, | |
{"password": "As_c]K", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "ae5bebbed836efa77e5b4779097fbfdb1859624e7f5774cf6c2114aaa7ea14d2"}, | |
{"password": "As_c]K5", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "ec102ee587d745eead06452ee0a8fd4fd8aaf4d2ea803f9e87918e1e0233223f"}, | |
{"password": "As_c]K5$", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "a1e5d6ef1d5bc87c66b128fb6afd069e3f9a88c6a58ad65b3908b1820e61f044"}, | |
{"password": "As_c]K5$J", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "c64cc5f045211f877c81a7a38bc58a71e9160548b2d25f3efdb8372769852212"}, | |
{"password": "As_c]K5$JI", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "3da9f519e45aedb871625e369effeddd954691d8bd73cd206dbdd1edfe89daa4"}, | |
{"password": "As_c]K5$JIm", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "376a5517bf8adc58ed5de0630a72c6e6a244f32f58c9f68435146b9119f0e134"}, | |
{"password": "As_c]K5$JIm_", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "369e02f4a36f705760d42ed5ec3fe6640fe99418d2185c9cb4545ea244ff6d43"}, | |
{"password": "As_c]K5$JIm_]", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "e9ebf9e9abd86ee3b466927e42bddae8eb34102b99bf16e3fa4f7a7ebd236371"}, | |
{"password": "As_c]K5$JIm_]3", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "3db9c7eb5acdadcce96638fc17b04f1ff909cbd0989b73cfc07bb30754939a8a"}, | |
{"password": "As_c]K5$JIm_]3o", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "7cdd235f4a7ffc9fa942c48e784344ad033454ee23b42d3f0fec7007161ba1d7"}, | |
{"password": "As_c]K5$JIm_]3oL", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "f89b8d269d796b664885d4aba104c3b3a7e9063578c1b83bf6786a6c5501dff5"}, | |
{"password": "As_c]K5$JIm_]3oL6", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "27e4ee3acee63ab154cb86d2f1fcdef5771348cd650015f1aad30d37ef643006"}, | |
{"password": "As_c]K5$JIm_]3oL68", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "3cb5e627b2beb4ac5394ebc5e5a684af8eda672340c11571adaf353698a5749c"}, | |
{"password": "As_c]K5$JIm_]3oL68V", "salt_hex": "010203", "extra_rounds": 100, "result_hex": "d1228e8462488b188175b884fe46de1529a829f73bede78546ba62fe09972817"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 0, "result_hex": "ce369a05c759c288465cc2ef274a1508c515dc87ad28c4c1658048e2fa3fa2f8"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 1, "result_hex": "e15a958bb97dc0df409d8629ab32bc2de4750da850efb8f8576b246536e9990e"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 2, "result_hex": "94e65add43759e1d4d68c829d518a320cf0dd1e5908cc429559ef9288af9d1e3"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 3, "result_hex": "91f528157275ca0d30435d1e64b73f54732dfdfe6861179af849531560a51ab5"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 4, "result_hex": "6ba4d409b02c556fab6a1b4f0ff8011beae551d72d6e156dc93f674c34e55028"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 5, "result_hex": "ec0e907230e71b976fdc5bc4e2e60d2a5ce60cde2b5324c4b3a82ee9b9f70f2a"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 6, "result_hex": "3ebfdf4b70c691cfa22b6f49a09ee0c7b88b6f82b66a968f95bdcfc09159001d"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 7, "result_hex": "5d57ea29e3f86fde30bb96182143d78e2e82e0dba33f896e849fdc01c30082e4"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 8, "result_hex": "012b570c617d237099aef822dfeb383928dfb83a605a6e74093bfaf120024f2d"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 9, "result_hex": "d81b2ed1a08b35fa2ccbb15274eb83afc229c1c6e80c8f1ff95bee225287dd64"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 10, "result_hex": "f2d8e1c2fbf72dc378855e2f86f4cf30b80302da339930a21c0e40beb8512ef6"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 11, "result_hex": "27e8c35d6fefc77bb382412ad0bc5414129590b692d7bc6e3aef519e02ad1420"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 12, "result_hex": "fd2f7d2d7490ef6ac078712c08fe9db7590c12d76163ef45c62751b772e79f0d"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 13, "result_hex": "f3e8e20d53e05b516ead13141b575a37d63e796251197f6bf83442e214723727"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 14, "result_hex": "f3f7e8ac8491e6807ff3cb7a966f13c0828d0ae3e81d9dd0290e2ba99f2dde86"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 15, "result_hex": "e267e89b7796464520b050e0384a695abe146f154bb3f656319e1d7f31ca3939"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 16, "result_hex": "dc239ddf195a8f4a3f7b1ce6b2d193a29b7c6e24d7e65f9d4e11202c51436e6c"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 17, "result_hex": "88138424c253bee4d4f3c1558024194c188c3c3919e137ba021aa74bbc906383"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 18, "result_hex": "fa82dc04adb0739974cd3c3d70b2e4f49be296fcd8f571e5a10aae957a46e6f2"}, | |
{"password": "very secret", "salt_hex": "010203", "extra_rounds": 19, "result_hex": "5af99dd2ca7ad8632b59249fa51cb87d15124539ef3cc4dd45cf2e0cc5d1b05d"}, | |
] | |
def test(): | |
for v in test_vectors: | |
actual = iterated_hmacsha256( | |
password = v["password"].encode("utf-8"), | |
salt = bytes.fromhex(v["salt_hex"]), | |
extra_rounds = v["extra_rounds"], | |
) | |
expected = bytes.fromhex(v["result_hex"]) | |
assert actual == expected, "got result %s for test vector %s"%(actual.hex(), v) | |
print("All test vectors match") | |
if __name__ == "__main__": | |
test() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment