From d7576d7d31bbd872b3df5a817de779762bddedec Mon Sep 17 00:00:00 2001 From: Victor Wagner Date: Mon, 14 Jul 2014 13:41:26 +0400 Subject: [PATCH] Added pbkdf module --- ctypescrypto/pbkdf2.py | 33 +++++++++++++++++++++++++++++++++ tests/testpbkdf.py | 22 ++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 ctypescrypto/pbkdf2.py create mode 100644 tests/testpbkdf.py diff --git a/ctypescrypto/pbkdf2.py b/ctypescrypto/pbkdf2.py new file mode 100644 index 0000000..0c2b077 --- /dev/null +++ b/ctypescrypto/pbkdf2.py @@ -0,0 +1,33 @@ +""" +PKCS5 PBKDF2 function. + +""" + +from ctypes import c_char_p,c_int, c_void_p, create_string_buffer +from ctypescrypto import libcrypto +from ctypescrypto.digest import DigestType + +def pbkdf2(password,salt,outlen,digesttype="sha1",iterations=2000): + """ + Interface to PKCS5_PBKDF2_HMAC function + Parameters: + + @param password - password to derive key from + @param salt - random salt to use for key derivation + @param outlen - number of bytes to derive + @param digesttype - name of digest to use to use (default sha1) + @param iterations - number of iterations to use + + @returns outlen bytes of key material derived from password and salt + """ + dt=DigestType(digesttype) + out=create_string_buffer(outlen) + res=libcrypto.PKCS5_PBKDF2_HMAC(password,len(password),salt,len(salt), + iterations,dt.digest,outlen,out) + if res<=0: + raise LibCryptoError("error computing PBKDF2") + return out.raw + +libcrypto.PKCS5_PBKDF2_HMAC.argtypes=(c_char_p,c_int,c_char_p,c_int,c_int, + c_void_p,c_int,c_char_p) +libcrypto.PKCS5_PBKDF2_HMAC.restupe=c_int diff --git a/tests/testpbkdf.py b/tests/testpbkdf.py new file mode 100644 index 0000000..dac46b4 --- /dev/null +++ b/tests/testpbkdf.py @@ -0,0 +1,22 @@ +from ctypescrypto.pbkdf2 import pbkdf2 +import unittest + +class TestPBKDF2(unittest.TestCase): + answersha1='\xc13\xb3\xc8\x80\xc2\t\x01\xdaR]\x08\x03\xaf>\x85\xed\x9bU\xf0\x89\n\x81Ctu\xee\xe3\xfe\xd9\xfd\x85\xe2"\x8c\xfbQ\xfeb4\x8f(ZF\xfd\xc3w\x13' + answersha256='oY\xaf\xf7\xfeB7@\xa80%\t\'\xd5r0\xbe\xb4\xf7\xe6TQ\xd2|Tx\xc0e\xff[0a\xe56\xec\xff\xda\xcd\xed~\xbde\xad"\xe8\t\x01o' + answersha1_1000='\xe9\xfe\xbf\xf5K\xfc\xe6h\xfd\xe3\x01\xac\xc8Uc\xcc\x9d\xc7\x1e\xf6\xf8\xd7\xaa\xef\x06se\xbe\x0e^e"\xefa\xba\xe1\xb0\x0b\xc1;\xcd\x05G<\xcc\rE\xfb' + def test_defaults(self): + d=pbkdf2("password","saltsalt",48) + self.assertEqual(d,self.answersha1) + def test_sha1(self): + d=pbkdf2("password","saltsalt",48,digesttype="sha1",iterations=2000) + self.assertEqual(d,self.answersha1) + def test_1000iter(self): + d=pbkdf2("password","saltsalt",48,digesttype="sha1",iterations=1000) + self.assertEqual(d,self.answersha1_1000) + def test_sha256(self): + d=pbkdf2("password","\01\02\03\04\0abc",48,digesttype="sha256") + self.assertEqual(d,self.answersha256) + +if __name__ == "__main__": + unittest.main() -- 2.39.2