Merge pull request #73 from d0/master

Updated regression tests and simplified code a bit
This commit is contained in:
Frank Morgner
2016-03-07 01:56:17 +01:00
2 changed files with 15 additions and 10 deletions

View File

@@ -203,11 +203,12 @@ def protect_string(string, password, cipherspec=None):
#Derive a key and a salt from password
pbk = crypt(password)
regex = re.compile('\$p5k2\$\$[\w./]*\$')
regex = re.compile('\$p5k2\$(\d*)\$([\w./]*)\$([\w./]*)')
match = regex.match(pbk)
if match != None:
salt = pbk[7:match.end()-1]
key = pbk[match.end():]
iterations = match.group(1)
salt = match.group(2)
key = match.group(3)
else:
raise ValueError
@@ -231,11 +232,11 @@ def read_protected_string(string, password, cipherspec=None):
hmac_length = 32 #FIXME: Ugly
#Check if the string has the structure, that is generated by protect_string
regex = re.compile('\$p5k2\$\$[\w./]*\$')
regex = re.compile('\$p5k2\$\$([\w./]*)\$')
match = regex.match(string)
if match != None:
salt = match.group(1)
crypted = string[match.end():len(string) - hmac_length]
salt = string[7:match.end() - 1]
hmac = string[len(string) - hmac_length:]
else:
raise ValueError("Wrong string format")
@@ -323,8 +324,7 @@ def crypt(word, salt=None, iterations=None):
else:
salt = "$p5k2$%x$%s" % (iterations, salt)
rawhash = pbkdf2_hmac('sha1', salt, word, iterations, 24)
# return salt + "$" + b64encode(rawhash, "./") DO: Original return line
return salt + "$" + rawhash
return salt + "$" + b64encode(rawhash, "./")
def _makesalt():
"""Return a 48-bit pseudorandom salt for crypt().

View File

@@ -30,9 +30,10 @@ class TestCryptoUtils(unittest.TestCase):
# The data generated by protect_string should actually consist of
# printable characters only but that would break backwards
# compatibility with the (buggy) legacy implementation
self.protectedTestString = "2470356b322424504f63775949487224ffa330e33b2d76b82e91a4c88ff722414d3522bcbdb8a4a45cd7c61963b52825e1361354d5b5efbcfeabfb66fa3f97dfecd5e57617b8e0172017785f4001e9653366363763323639363965313261386363623738326435326639653563633339".decode('hex')
self.protectedTestString = "2470356b32242478424f50746f6d712448b8f6285ac8462fffc6aef921f2ad84855219c5aaafb39c4cc9e54d1634c60cfc9347c67fa55967c5b0130469c96a44f0b73c53f5ddfc43cd8c1ef68965ebb23330393265383732333937353465653838643135363830666637336134316532".decode('hex')
self.salt = "POcwYIHr"
self.cryptedWord = "2470356b322424504f63775949487224993c1d36e308d941d0fa240d18f4097ce8d0995226f04800".decode('hex')
self.cryptedWord = "$p5k2$$POcwYIHr$SPaWqD3NpmLZc6gXbeybnAoCxo7Oc//K"
self.cryptedWordThousandIterations = "$p5k2$3e8$POcwYIHr$f/mEOCulo6v7Nq2ooS3480xTet6zdGbI"
def test_padding(self):
padded = append_padding(16, self.teststring)
@@ -49,8 +50,12 @@ class TestCryptoUtils(unittest.TestCase):
self.assertEqual(unprotectedString, self.teststring)
def test_crypt(self):
cryptedWord = crypt(self.teststring, self.salt, 400)
cryptedWord = crypt(self.teststring, self.salt)
self.assertEqual(cryptedWord, self.cryptedWord)
def test_crypt_non_default_iterations(self):
cryptedWord = crypt(self.teststring, self.salt, 1000)
self.assertEqual(cryptedWord, self.cryptedWordThousandIterations)
if __name__ == "__main__":
unittest.main()