Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from __future__ import print_function
- import os
- import base64
- import hashlib
- import hmac
- import sys
- import binascii
- import json
- import ast
- from Crypto.Cipher import AES
- from Crypto.Protocol import KDF
- from Crypto.Hash import HMAC, SHA256
- from Crypto import Random
- #testing password
- PASSWORD = '1234'
- PY2 = sys.version_info[0] == 2
- PY3 = sys.version_info[0] == 3
- if PY2:
- def to_bytes(s):
- if isinstance(s, str):
- return s
- if isinstance(s, unicode):
- return s.encode('utf-8')
- to_str = to_bytes
- def bchr(s):
- return chr(s)
- def bord(s):
- return ord(s)
- elif PY3:
- def to_bytes(s):
- if isinstance(s, bytes):
- return s
- if isinstance(s, str):
- return s.encode('utf-8')
- def to_str(s):
- if isinstance(s, bytes):
- return s.decode('utf-8')
- elif isinstance(s, str):
- return s
- def bchr(s):
- return bytes([s])
- def bord(s):
- return s
- class RNCryptor(object):
- AES_BLOCK_SIZE = AES.block_size
- AES_MODE = AES.MODE_CBC
- SALT_SIZE = 8
- def pre_decrypt_data(self, data):
- """Handle data before decryption."""
- data = to_bytes(data)
- return data
- def post_decrypt_data(self, data):
- """Remove padding for AES (PKCS#7)."""
- data = data[:-bord(data[-1])]
- return to_str(data)
- def decrypt(self, data, password):
- data = self.pre_decrypt_data(data)
- password = to_bytes(password)
- n = len(data)
- version = data[0]
- options = data[1]
- encryption_salt = data[2:10]
- hmac_salt = data[10:18]
- iv = data[18:34]
- cipher_text = data[34:n - 32]
- hmac = data[n - 32:]
- print()
- print('Version : ' + binascii.hexlify(version))
- print('Options : ' + binascii.hexlify(options))
- print('Encryption salt: ' + binascii.hexlify(encryption_salt))
- print('HMAC salt : ' + binascii.hexlify(hmac_salt))
- print('IV : ' + binascii.hexlify(iv))
- print('Cipher text : ' + binascii.hexlify(cipher_text))
- print('HMAC : ' + binascii.hexlify(hmac))
- if binascii.hexlify(options) == '02':
- # Coming from Android encryption with only 1000 iterations in pbkdf2 instead of 10000
- iterations = 1000
- else:
- iterations = 10000
- encryption_key = self._pbkdf2(password, encryption_salt, iterations=iterations)
- hmac_key = self._pbkdf2(password, hmac_salt, iterations=iterations)
- print('HMAC KEY : ' + binascii.hexlify(hmac_key))
- if self._hmac(hmac_key, data[:n-32]) != hmac:
- raise Exception("HMACs do not match")
- decrypted_data = self._aes_decrypt(encryption_key, iv, cipher_text)
- return self.post_decrypt_data(decrypted_data)
- def pre_encrypt_data(self, data):
- """Padding for the data for AES (PKCS#7)."""
- data = to_bytes(data)
- rem = self.AES_BLOCK_SIZE - len(data) % self.AES_BLOCK_SIZE
- return data + bchr(rem) * rem
- def post_encrypt_data(self, data):
- """Handle data after encryption."""
- return data
- def encrypt(self, data, password):
- data = self.pre_encrypt_data(data)
- password = to_bytes(password)
- encryption_salt = self.encryption_salt
- print("*** Encryption salt:", binascii.hexlify(encryption_salt))
- encryption_key = self._pbkdf2(password, encryption_salt)
- print("*** Encryption key:", binascii.hexlify(encryption_key))
- hmac_salt = self.hmac_salt
- print("*** HMAC salt:", binascii.hexlify(hmac_salt))
- hmac_key = self._pbkdf2(password, hmac_salt)
- print("*** HMAC key:", binascii.hexlify(hmac_key))
- iv = self.iv
- print("*** IV:", binascii.hexlify(iv))
- cipher_text = self._aes_encrypt(encryption_key, iv, data)
- print("*** Ciphertext:", binascii.hexlify(cipher_text))
- version = b'\x03'
- options = b'\x01'
- new_data = b''.join([version, options, encryption_salt, hmac_salt, iv, cipher_text])
- encrypted_data = new_data + self._hmac(hmac_key, new_data)
- return self.post_encrypt_data(encrypted_data)
- @property
- def encryption_salt(self):
- return Random.new().read(self.SALT_SIZE)
- @property
- def hmac_salt(self):
- return Random.new().read(self.SALT_SIZE)
- @property
- def iv(self):
- return Random.new().read(self.AES_BLOCK_SIZE)
- def _aes_encrypt(self, key, iv, text):
- return AES.new(key, self.AES_MODE, iv).encrypt(text)
- def _aes_decrypt(self, key, iv, text):
- return AES.new(key, self.AES_MODE, iv).decrypt(text)
- def _hmac(self, key, data):
- print('\nLocally Generated HMAC: ' + binascii.hexlify(hmac.new(key, data, hashlib.sha256).digest()))
- return hmac.new(key, data, hashlib.sha256).digest()
- def _pbkdf2(self, password, salt, iterations=10000, key_length=32):
- return KDF.PBKDF2(password, salt, dkLen=key_length, count=iterations,
- prf=lambda p, s: hmac.new(p, s, hashlib.sha256).digest())
- def encrypt_json(json):
- cryptor = RNCryptor()
- encryptedText = cryptor.encrypt(json, PASSWORD)
- hex_output = binascii.hexlify(encryptedText)
- print(hex_output)
- def decrypt_json(client_input):
- cryptor = RNCryptor()
- data_to_decrypt = binascii.unhexlify(client_input)
- decrypted_text = cryptor.decrypt(data_to_decrypt, PASSWORD)
- return decrypted_text
- def decrypt(message):
- decrypted_json = ast.literal_eval(decrypt_json(message))
- print(decrypted_json)
- # decrypt_json("Ciphertext")
- encrypt_json('{"MESSAGE": "text"}')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement