def decrypt_json(enc, keys): """ Takes the object returned by encrypt_json earlier, and returns the original input object using the given keys. """ nonce, cipher, tag = map(b64_decode, [enc['nonce'], enc['cipher'], enc['tag']]) kconf, kauth = keys ourtag = hmac.new(kauth, nonce + cipher, sha256).digest() if len(nonce) != 8 or not hmac.compare_digest(ourtag, tag): raise IOError('corrupt ciphertext') plain = chacha.chacha20_cipher(kconf, nonce, cipher) plain = crypto.unpad(plain) return json.loads(plain.decode('utf8'))
def encrypt_json(js, keys, padding): """ Encrypt the json-encodable object js using the keys provided (get these from a secrets object). This returns a dict with items for the things you need to decrypt. """ nonce = os.urandom(8) plain = json.dumps(js).encode('utf8') plain = padding(plain) kconf, kauth = keys cipher = chacha.chacha20_cipher(kconf, nonce, plain) tag = hmac.new(kauth, nonce + cipher, sha256).digest() return dict( tag = b64_encode(tag), cipher = b64_encode(cipher), nonce = b64_encode(nonce) )