Creates Cryptographer. Separates decryptiomn from encrypted_blob

This commit is contained in:
Sergi Delgado Segura
2019-11-08 14:06:06 +00:00
parent f4f77fb39a
commit c08013abd0
2 changed files with 64 additions and 41 deletions

50
pisa/cryptographer.py Normal file
View File

@@ -0,0 +1,50 @@
from hashlib import sha256
from binascii import unhexlify, hexlify
from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from pisa.logger import Logger
logger = Logger("Cryptographer")
# FIXME: Cryptographer is assuming AES-128-GCM and SHA256 since they are the only pair accepted by the encrypted blob
# and the only pair programmed so far.
class Cryptographer:
@staticmethod
# ToDo: #20-test-tx-decrypting-edge-cases
def decrypt(encrypted_blob, key, rtype="hex"):
if rtype not in ["hex", "bytes"]:
raise ValueError("Wrong return type. Return type must be 'hex' or 'bytes'")
# master_key = H(tx_id | tx_id)
key = unhexlify(key)
master_key = sha256(key + key).digest()
# The 16 MSB of the master key will serve as the AES GCM 128 secret key. The 16 LSB will serve as the IV.
sk = master_key[:16]
nonce = master_key[16:]
logger.info(
"Creating new blob.",
master_key=hexlify(master_key).decode(),
sk=hexlify(sk).decode(),
nonce=hexlify(sk).decode(),
encrypted_blob=encrypted_blob.data,
)
# Decrypt
cipher = AESGCM(sk)
data = unhexlify(encrypted_blob.data.encode())
try:
blob = cipher.decrypt(nonce=nonce, data=data, associated_data=None)
# Change the blob encoding to hex depending on the rtype (default)
if rtype == "hex":
blob = hexlify(blob).decode("utf8")
except InvalidTag:
blob = None
return blob

View File

@@ -1,48 +1,21 @@
from hashlib import sha256
from binascii import unhexlify, hexlify
from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from pisa.logger import Logger
logger = Logger("Watcher")
from pisa.conf import SUPPORTED_CIPHERS, SUPPORTED_HASH_FUNCTIONS
# FIXME: EncryptedBlob is assuming AES-128-GCM. A cipher field should be part of the object and the decryption should be
# performed depending on the cipher.
class EncryptedBlob:
def __init__(self, data):
def __init__(self, data, cipher="AES-GCM-128", hash_function="SHA256"):
if cipher in SUPPORTED_CIPHERS:
self.cipher = cipher
else:
raise ValueError("Cipher not supported")
if hash_function in SUPPORTED_HASH_FUNCTIONS:
self.hash_function = hash_function
else:
raise ValueError("Hash function not supported")
self.data = data
def __eq__(self, other):
return isinstance(other, EncryptedBlob) and self.data == other.data
def decrypt(self, key):
# master_key = H(tx_id | tx_id)
key = unhexlify(key)
master_key = sha256(key + key).digest()
# The 16 MSB of the master key will serve as the AES GCM 128 secret key. The 16 LSB will serve as the IV.
sk = master_key[:16]
nonce = master_key[16:]
logger.info(
"Creating new blob.",
master_key=hexlify(master_key).decode(),
sk=hexlify(sk).decode(),
nonce=hexlify(sk).decode(),
encrypted_blob=self.data,
)
# Decrypt
aesgcm = AESGCM(sk)
data = unhexlify(self.data.encode())
try:
raw_tx = aesgcm.decrypt(nonce=nonce, data=data, associated_data=None)
hex_raw_tx = hexlify(raw_tx).decode("utf8")
except InvalidTag:
hex_raw_tx = None
return hex_raw_tx