|
2 | 2 |
|
3 | 3 | import hashlib
|
4 | 4 | import io
|
| 5 | +import os |
5 | 6 | from datetime import datetime, timezone
|
6 | 7 | from typing import BinaryIO
|
7 | 8 |
|
8 | 9 | from dissect.cstruct import cstruct
|
9 | 10 |
|
| 11 | +try: |
| 12 | + import _pystandalone |
| 13 | + |
| 14 | + HAS_PYSTANDALONE = True |
| 15 | +except ImportError: |
| 16 | + HAS_PYSTANDALONE = False |
| 17 | + |
10 | 18 | try:
|
11 | 19 | from Crypto.Cipher import AES, PKCS1_OAEP
|
12 | 20 | from Crypto.PublicKey import RSA
|
@@ -74,16 +82,26 @@ class EncryptedStream(io.RawIOBase):
|
74 | 82 | """
|
75 | 83 |
|
76 | 84 | def __init__(self, fh: BinaryIO, public_key: str):
|
77 |
| - if not HAS_PYCRYPTODOME: |
78 |
| - raise ImportError("PyCryptodome is not available") |
| 85 | + if not HAS_PYSTANDALONE and not HAS_PYCRYPTODOME: |
| 86 | + raise ImportError("Neither _pystandalone nor PyCryptodome are available") |
79 | 87 |
|
80 | 88 | self.fh = fh
|
81 | 89 |
|
82 |
| - key = get_random_bytes(32) |
83 |
| - iv = get_random_bytes(12) |
84 |
| - self.cipher = AES.new(key, AES.MODE_GCM, nonce=iv) |
85 |
| - |
86 |
| - rsa = PKCS1_OAEP.new(RSA.import_key(public_key)) |
| 90 | + if HAS_PYSTANDALONE: |
| 91 | + try: |
| 92 | + key = _pystandalone.rand_bytes(32) |
| 93 | + iv = _pystandalone.rand_bytes(12) |
| 94 | + except Exception: |
| 95 | + # Fallback if pystandalone does not work |
| 96 | + key = os.urandom(32) |
| 97 | + iv = os.urandom(12) |
| 98 | + self.cipher = _pystandalone.aes_256_gcm(key, iv) |
| 99 | + rsa = _pystandalone.rsa(public_key) |
| 100 | + else: |
| 101 | + key = get_random_bytes(32) |
| 102 | + iv = get_random_bytes(12) |
| 103 | + self.cipher = AES.new(key, AES.MODE_GCM, nonce=iv) |
| 104 | + rsa = PKCS1_OAEP.new(RSA.import_key(public_key)) |
87 | 105 |
|
88 | 106 | plain_header = c_acquire.header(
|
89 | 107 | magic=HEADER_MAGIC,
|
|
0 commit comments