Я предполагаю, что frame это [SciPy]: numpy.ndarray . Есть 2 проблемы. Ниже приведен пример:
code.py
#!/usr/bin/env python3
import sys
from Crypto.Cipher import AES
import numpy as np
import cv2
import base64
BLOCK_SIZE = 16
PADDING = b"{"
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
CIPHER_MODE = AES.MODE_CBC
SECRET = b"youwanttoknowmysecretdontyouhaha"
def main():
img0 = cv2.imread("c:/valmand.png")
encrypt_cipher = AES.new(SECRET, CIPHER_MODE) # Python 2: AES.new(SECRET)
print("Original image data - Type: {:}, Size: {:d}, Attrs: {:}".format(type(img0), img0.size, img0.shape))
img_stream_wrong = str(img0).encode()
print("\nWrong img0 stream length: {:}".format(len(img_stream_wrong)))
print("\nWrong img0 stream: {:}".format(img_stream_wrong))
img_stream = img0.tobytes()
print("\nCorrect img0 stream length: {:}".format(len(img_stream)))
encrypted = EncodeAES(encrypt_cipher, img_stream)
print("\nEncrypted length: {:d}".format(len(encrypted)))
decrypt_cipher = AES.new(SECRET, CIPHER_MODE) # Python 2: AES.new(SECRET)
decrypted = DecodeAES(decrypt_cipher, encrypted)
print("\nDecrypted length: {:d}".format(len(decrypted)))
img1 = np.frombuffer(decrypted, dtype=img0.dtype).reshape(img0.shape)
print("\nFinal image data - Type: {:}, Size: {:d}, Attrs: {:}".format(type(img1), img1.size, img1.shape))
#cv2.imshow("Capturing", img1)
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
Примечания
- Я упростил пример, чтобы загрузить только изображение
- Поскольку на Python 2 не установлены все необходимые пакеты, я использовал Python 3 . Вот почему были внесены некоторые изменения, не связанные с вопросом:
- Переключение с строки на байтов
- AES изменения:
AES.new
подпись изменена ( [PyCryptodome]: AES )
- Тот же шифр нельзя использовать для дешифрования после того, как он был использован для шифрования, поэтому создайте другой с теми же свойствами (возможно, есть какой-то более чистый способ сделать это, но я не тратил на него слишком много времени)
Ошибки :
выход
e:\Work\Dev\StackOverflow\q054326620>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32
Original image data - Type: <class 'numpy.ndarray'>, Size: 1493331, Attrs: (799, 623, 3)
Wrong img0 stream length: 629
Wrong img0 stream: b'[[[255 255 255]\n [255 255 255]\n [255 255 255]\n ...\n [255 255 255]\n [255 255 255]\n [255 255 255]]\n\n [[255 255 255]\n [255 255 255]\n [255 255 255]\n ...\n [255 255 255]\n [255 255 255]\n [255 255 255]]\n\n [[255 255 255]\n [255 255 255]\n [255 255 255]\n ...\n [255 255 255]\n [255 255 255]\n [255 255 255]]\n\n ...\n\n [[255 255 255]\n [255 255 255]\n [255 255 255]\n ...\n [255 255 255]\n [255 255 255]\n [255 255 255]]\n\n [[255 255 255]\n [255 255 255]\n [255 255 255]\n ...\n [255 255 255]\n [255 255 255]\n [255 255 255]]\n\n [[255 255 255]\n [255 255 255]\n [255 255 255]\n ...\n [255 255 255]\n [255 255 255]\n [255 255 255]]]'
Correct img0 stream length: 1493331
Encrypted length: 1991128
Decrypted length: 1493331
Final image data - Type: <class 'numpy.ndarray'>, Size: 1493331, Attrs: (799, 623, 3)
@ EDIT0
Видимо, есть некоторые проблемы с совместимостью. Я разработал ответ, используя Python 3 и pycrpytodome 3.7.2 . Я обновил до последней ( 3.7.3 ), я также установил его на Python 2 , и приведенный выше код работает. Вот что я получаю в консоли:
>>> from Crypto.Cipher import AES
>>> AES
<module 'Crypto.Cipher.AES' from 'e:\Work\Dev\VEnvs\py_064_02.07.15_test0\lib\site-packages\Crypto\Cipher\AES.pyc'>
>>> AES.new("")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: new() takes at least 2 arguments (1 given)
>>> import Crypto
>>> Crypto.__version__
'3.7.3'
Итак, у вас, вероятно, ужасно старая pycryptodome версия. В любом случае, я вслепую отправляю изменения, требуемые вашим кодом, чтобы включить исправления (, в то время как цикл только ):
# The rest of your code (exactly as in the question)
while True:
a = a + 1
check, frame = video.read()
original_meta = frame.dtype.name, frame.shape
encrypted_meta = EncodeAES(cipher, bytes(original_meta))
encrypted_data = EncodeAES(cipher, frame.tobytes())
# Here is the separation
decrypted_meta = DecodeAES(cipher, encrypted_meta)
decrypted_data = DecodeAES(cipher, encrypted_data)
meta = ast.literal_eval(decrypted_meta)
img = np.frombuffer(decrypted_data, dtype=np.dtype(meta[0])).reshape(meta[1])
cv2.imshow("Capturing", img)
key = cv2.waitKey(1)
if key == ord("q"):
break