Advertisement
Guest User

RNCryptor-python.py

a guest
Sep 20th, 2015
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.95 KB | None | 0 0
  1. from __future__ import print_function
  2.  
  3. import os
  4. import base64
  5. import hashlib
  6. import hmac
  7. import sys
  8. import binascii
  9. import json
  10. import ast
  11.  
  12. from Crypto.Cipher import AES
  13. from Crypto.Protocol import KDF
  14. from Crypto.Hash import HMAC, SHA256
  15. from Crypto import Random
  16.  
  17. #testing password
  18. PASSWORD = '1234'
  19.  
  20. PY2 = sys.version_info[0] == 2
  21. PY3 = sys.version_info[0] == 3
  22.  
  23. if PY2:
  24.     def to_bytes(s):
  25.         if isinstance(s, str):
  26.             return s
  27.         if isinstance(s, unicode):
  28.             return s.encode('utf-8')
  29.  
  30.     to_str = to_bytes
  31.    
  32.     def bchr(s):
  33.         return chr(s)
  34.    
  35.     def bord(s):
  36.         return ord(s)
  37.  
  38. elif PY3:
  39.     def to_bytes(s):
  40.         if isinstance(s, bytes):
  41.             return s
  42.         if isinstance(s, str):
  43.             return s.encode('utf-8')
  44.  
  45.     def to_str(s):
  46.         if isinstance(s, bytes):
  47.             return s.decode('utf-8')
  48.         elif isinstance(s, str):
  49.             return s
  50.                    
  51.     def bchr(s):
  52.         return bytes([s])
  53.  
  54.     def bord(s):
  55.         return s
  56.  
  57.  
  58. class RNCryptor(object):
  59.    
  60.     AES_BLOCK_SIZE = AES.block_size
  61.     AES_MODE = AES.MODE_CBC
  62.     SALT_SIZE = 8
  63.    
  64.     def pre_decrypt_data(self, data):
  65.         """Handle data before decryption."""
  66.         data = to_bytes(data)
  67.         return data
  68.    
  69.     def post_decrypt_data(self, data):
  70.         """Remove padding for AES (PKCS#7)."""
  71.         data = data[:-bord(data[-1])]
  72.         return to_str(data)
  73.    
  74.     def decrypt(self, data, password):
  75.         data = self.pre_decrypt_data(data)
  76.         password = to_bytes(password)
  77.        
  78.         n = len(data)
  79.        
  80.         version = data[0]
  81.         options = data[1]
  82.         encryption_salt = data[2:10]
  83.         hmac_salt = data[10:18]
  84.         iv = data[18:34]
  85.         cipher_text = data[34:n - 32]
  86.         hmac = data[n - 32:]
  87.  
  88.         print()
  89.         print('Version        : ' + binascii.hexlify(version))
  90.         print('Options        : ' + binascii.hexlify(options))
  91.         print('Encryption salt: ' + binascii.hexlify(encryption_salt))
  92.         print('HMAC salt      : ' + binascii.hexlify(hmac_salt))
  93.         print('IV             : ' + binascii.hexlify(iv))
  94.         print('Cipher text    : ' + binascii.hexlify(cipher_text))
  95.         print('HMAC           : ' + binascii.hexlify(hmac))
  96.  
  97.         if binascii.hexlify(options) == '02':
  98.             # Coming from Android encryption with only 1000 iterations in pbkdf2 instead of 10000
  99.             iterations = 1000
  100.         else:
  101.             iterations = 10000
  102.  
  103.         encryption_key = self._pbkdf2(password, encryption_salt, iterations=iterations)
  104.         hmac_key = self._pbkdf2(password, hmac_salt, iterations=iterations)
  105.         print('HMAC KEY       : ' + binascii.hexlify(hmac_key))
  106.  
  107.         if self._hmac(hmac_key, data[:n-32]) != hmac:
  108.             raise Exception("HMACs do not match")
  109.  
  110.         decrypted_data = self._aes_decrypt(encryption_key, iv, cipher_text)
  111.        
  112.         return self.post_decrypt_data(decrypted_data)
  113.  
  114.     def pre_encrypt_data(self, data):
  115.         """Padding for the data for AES (PKCS#7)."""
  116.         data = to_bytes(data)
  117.         rem = self.AES_BLOCK_SIZE - len(data) % self.AES_BLOCK_SIZE
  118.         return data + bchr(rem) * rem
  119.  
  120.     def post_encrypt_data(self, data):
  121.         """Handle data after encryption."""
  122.        
  123.         return data
  124.  
  125.     def encrypt(self, data, password):
  126.         data = self.pre_encrypt_data(data)
  127.         password = to_bytes(password)
  128.        
  129.         encryption_salt = self.encryption_salt
  130.         print("*** Encryption salt:", binascii.hexlify(encryption_salt))
  131.         encryption_key = self._pbkdf2(password, encryption_salt)
  132.         print("*** Encryption key:", binascii.hexlify(encryption_key))
  133.  
  134.         hmac_salt = self.hmac_salt
  135.         print("*** HMAC salt:", binascii.hexlify(hmac_salt))
  136.         hmac_key = self._pbkdf2(password, hmac_salt)
  137.         print("*** HMAC key:", binascii.hexlify(hmac_key))
  138.  
  139.         iv = self.iv
  140.         print("*** IV:", binascii.hexlify(iv))
  141.         cipher_text = self._aes_encrypt(encryption_key, iv, data)
  142.         print("*** Ciphertext:", binascii.hexlify(cipher_text))
  143.  
  144.         version = b'\x03'
  145.         options = b'\x01'
  146.        
  147.         new_data = b''.join([version, options, encryption_salt, hmac_salt, iv, cipher_text])
  148.         encrypted_data = new_data + self._hmac(hmac_key, new_data)
  149.        
  150.         return self.post_encrypt_data(encrypted_data)
  151.    
  152.     @property
  153.     def encryption_salt(self):
  154.         return Random.new().read(self.SALT_SIZE)
  155.    
  156.     @property
  157.     def hmac_salt(self):
  158.         return Random.new().read(self.SALT_SIZE)
  159.    
  160.     @property
  161.     def iv(self):
  162.         return Random.new().read(self.AES_BLOCK_SIZE)
  163.    
  164.     def _aes_encrypt(self, key, iv, text):
  165.         return AES.new(key, self.AES_MODE, iv).encrypt(text)
  166.    
  167.     def _aes_decrypt(self, key, iv, text):
  168.         return AES.new(key, self.AES_MODE, iv).decrypt(text)
  169.    
  170.     def _hmac(self, key, data):
  171.         print('\nLocally Generated HMAC: ' + binascii.hexlify(hmac.new(key, data, hashlib.sha256).digest()))
  172.         return hmac.new(key, data, hashlib.sha256).digest()
  173.    
  174.     def _pbkdf2(self, password, salt, iterations=10000, key_length=32):
  175.         return KDF.PBKDF2(password, salt, dkLen=key_length, count=iterations,
  176.                           prf=lambda p, s: hmac.new(p, s, hashlib.sha256).digest())
  177.  
  178.  
  179. def encrypt_json(json):
  180.     cryptor = RNCryptor()
  181.     encryptedText = cryptor.encrypt(json, PASSWORD)
  182.     hex_output = binascii.hexlify(encryptedText)
  183.     print(hex_output)
  184.  
  185.  
  186. def decrypt_json(client_input):
  187.     cryptor = RNCryptor()
  188.     data_to_decrypt = binascii.unhexlify(client_input)
  189.     decrypted_text = cryptor.decrypt(data_to_decrypt, PASSWORD)
  190.     return decrypted_text
  191.  
  192.  
  193. def decrypt(message):
  194.     decrypted_json = ast.literal_eval(decrypt_json(message))
  195.     print(decrypted_json)
  196.  
  197.  
  198. # decrypt_json("Ciphertext")
  199. encrypt_json('{"MESSAGE": "text"}')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement