crypto.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. from ctypes import cdll, c_char_p, c_int, c_uint, c_void_p, POINTER, create_string_buffer
  2. from ctypes.util import find_library
  3. import struct
  4. libcrypto = cdll.LoadLibrary(find_library('crypto'))
  5. 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)
  6. libcrypto.EVP_sha256.restype = c_void_p
  7. libcrypto.AES_set_encrypt_key.argtypes = (c_char_p, c_int, c_char_p)
  8. libcrypto.AES_ctr128_encrypt.argtypes = (c_char_p, c_char_p, c_int, c_char_p, c_char_p, c_char_p, POINTER(c_uint))
  9. _int = struct.Struct('>I')
  10. _long = struct.Struct('>Q')
  11. bytes_to_int = lambda x, offset=0: _int.unpack_from(x, offset)[0]
  12. bytes_to_long = lambda x, offset=0: _long.unpack_from(x, offset)[0]
  13. long_to_bytes = lambda x: _long.pack(x)
  14. def pbkdf2_sha256(password, salt, iterations, size):
  15. key = create_string_buffer(size)
  16. rv = libcrypto.PKCS5_PBKDF2_HMAC(password, len(password), salt, len(salt), iterations, libcrypto.EVP_sha256(), size, key)
  17. if not rv:
  18. raise Exception('PKCS5_PBKDF2_HMAC failed')
  19. return key.raw
  20. def get_random_bytes(n):
  21. """Return n cryptographically strong pseudo-random bytes
  22. """
  23. buf = create_string_buffer(n)
  24. if not libcrypto.RAND_bytes(buf, n):
  25. raise Exception('RAND_bytes failed')
  26. return buf.raw
  27. class AES:
  28. def __init__(self, key, iv=None):
  29. self.key = create_string_buffer(2000)
  30. self.iv = create_string_buffer(16)
  31. self.buf = create_string_buffer(16)
  32. self.num = c_uint()
  33. self.reset(key, iv)
  34. def reset(self, key=None, iv=None):
  35. if key:
  36. libcrypto.AES_set_encrypt_key(key, len(key) * 8, self.key)
  37. if iv:
  38. self.iv.raw = iv
  39. self.num.value = 0
  40. def encrypt(self, data):
  41. out = create_string_buffer(len(data))
  42. libcrypto.AES_ctr128_encrypt(data, out, len(data), self.key, self.iv, self.buf, self.num)
  43. return out.raw
  44. decrypt = encrypt