]> wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
Added pbkdf module
authorVictor Wagner <vitus@wagner.pp.ru>
Mon, 14 Jul 2014 09:41:26 +0000 (13:41 +0400)
committerVictor Wagner <vitus@wagner.pp.ru>
Mon, 14 Jul 2014 09:41:26 +0000 (13:41 +0400)
ctypescrypto/pbkdf2.py [new file with mode: 0644]
tests/testpbkdf.py [new file with mode: 0644]

diff --git a/ctypescrypto/pbkdf2.py b/ctypescrypto/pbkdf2.py
new file mode 100644 (file)
index 0000000..0c2b077
--- /dev/null
@@ -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 (file)
index 0000000..dac46b4
--- /dev/null
@@ -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()