update
parent
c68c0e138f
commit
f5fcb21d73
@ -1,3 +1,4 @@
|
||||
thumbnails/
|
||||
images/
|
||||
messages.html
|
||||
*.html
|
||||
__pycache__/
|
||||
|
Binary file not shown.
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
import json
|
||||
import unpaddedbase64
|
||||
from Crypto import Random
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Hash import SHA256
|
||||
from Crypto.Util import Counter
|
||||
|
||||
class EncryptionError(Exception):
|
||||
pass
|
||||
|
||||
def decrypt(ciphertext: bytes, key: str, hash: str, iv: str):
|
||||
"""Decrypt an encrypted attachment.
|
||||
Args:
|
||||
ciphertext (bytes): The data to decrypt.
|
||||
key (str): AES_CTR JWK key object.
|
||||
hash (str): Base64 encoded SHA-256 hash of the ciphertext.
|
||||
iv (str): Base64 encoded 16 byte AES-CTR IV.
|
||||
Returns:
|
||||
The plaintext bytes.
|
||||
Raises:
|
||||
EncryptionError if the integrity check fails.
|
||||
"""
|
||||
expected_hash = unpaddedbase64.decode_base64(hash)
|
||||
|
||||
h = SHA256.new()
|
||||
h.update(ciphertext)
|
||||
|
||||
if h.digest() != expected_hash:
|
||||
raise EncryptionError("Mismatched SHA-256 digest.")
|
||||
|
||||
try:
|
||||
byte_key: bytes = unpaddedbase64.decode_base64(key)
|
||||
except (BinAsciiError, TypeError):
|
||||
raise EncryptionError("Error decoding key.")
|
||||
|
||||
try:
|
||||
# Drop last 8 bytes, which are 0
|
||||
byte_iv: bytes = unpaddedbase64.decode_base64(iv)[:8]
|
||||
except (BinAsciiError, TypeError):
|
||||
raise EncryptionError("Error decoding initial values.")
|
||||
|
||||
ctr = Counter.new(64, prefix=byte_iv, initial_value=0)
|
||||
|
||||
try:
|
||||
cipher = AES.new(byte_key, AES.MODE_CTR, counter=ctr)
|
||||
except ValueError as e:
|
||||
raise EncryptionError(e)
|
||||
|
||||
return cipher.decrypt(ciphertext)
|
||||
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# with open('images/output', 'wb') as output:
|
||||
# with open('images/LUJAssHxtTWsnYPbSlTcMdvl.octet-stream', 'rb') as cipher:
|
||||
# with open('images/LUJAssHxtTWsnYPbSlTcMdvl.metadata', 'r') as rawmeta:
|
||||
# meta = json.load(rawmeta)
|
||||
# key = meta['file']['key']
|
||||
# decrypted = decrypt_attachment(cipher.read(), key['k'], meta['file']['hashes']['sha256'], meta['file']['iv'])
|
||||
# output.write(decrypted)
|
||||
|
||||
|
Loading…
Reference in New Issue