使用 CryptoJs 加密文件并使用 Python 解密 (AES CBC)

Wae*_*mas 5 javascript python encryption cryptography cryptojs

我正在尝试在 Javascript (ReactJs) 中加密文件(尝试使用 png),并且希望能够解密文件并在 Python 中恢复其原始状态。

我尝试了多种方法,但下面的 JS 代码是我能正常工作的唯一一种。通过 JS 代码,我能够以原始形式取回 png。然而,当我不断得到时,我似乎缺少一些填充的东西:

Traceback (most recent call last):
  File "***/encrypt_decrypt_using_aes.py", line 110, in <module>
    decrypted = decrypt(encData, key, iv)
  File "***/encrypt_decrypt_using_aes.py", line 103, in decrypt
    return unpad(cipher.decrypt(enc),16)
  File "/usr/local/lib/python3.9/site-packages/Crypto/Util/Padding.py", line 90, in unpad
    raise ValueError("Padding is incorrect.")
ValueError: Padding is incorrect.
Run Code Online (Sandbox Code Playgroud)

我尝试使用 ZeroPadding、NoPadding、PKCS7,但没有任何效果。

对我所缺少的有什么想法吗?

JS代码:

    function decrypt(input) {
      var file = input;
      var reader = new FileReader();
      reader.onload = () => {
          var key = "1234567887654321";  
    
          var decrypted = CryptoJS.AES.decrypt(reader.result, key, {mode: CryptoJS.mode.CBC});               // Decryption: I: Base64 encoded string (OpenSSL-format) -> O: WordArray
          var typedArray = convertWordArrayToUint8Array(decrypted);               // Convert: WordArray -> typed array
    
          var fileDec = new Blob([typedArray]);                                   // Create blob from typed array
    
          var a = document.createElement("a");
          var url = window.URL.createObjectURL(fileDec);
          var filename = file.name.substr(0, file.name.length - 4);
          a.href = url;
          a.download = filename;
          a.click();
          window.URL.revokeObjectURL(url);
      };
      reader.readAsText(file);
    }

    function encrypt(input) {
      var file = input
      console.log("In Encrypt")
      console.log(file)
      var reader = new FileReader();
      var iv = CryptoJS.enc.Utf8.parse('53509bee-8207-11');
      reader.onload = () => {
          var key = "1234567887654321";
          var wordArray = CryptoJS.lib.WordArray.create(reader.result);           // Convert: ArrayBuffer -> WordArray
          var encrypted = CryptoJS.AES.encrypt(wordArray, key, {iv: iv, mode: CryptoJS.mode.CBC}).toString();        // Encryption: I: WordArray -> O: -> Base64 encoded string (OpenSSL-format)
  
          var fileEnc = new Blob([encrypted]);                                    // Create blob from string
  
          // var a = document.createElement("a");
          // var url = window.URL.createObjectURL(fileEnc);
          var filename = input.name + ".enc";
          console.log(filename)
          var file = new File([fileEnc], filename);
          // a.href = url;
          // a.download = filename;
          // a.click();
          // window.URL.revokeObjectURL(url);
          setFiles2State(files2State => ({
            fileList2: [...files2State.fileList2, file],
          }));
          console.log("OUT LIST")
          console.log(files2State)
      };


      reader.readAsArrayBuffer(file);

  }
Run Code Online (Sandbox Code Playgroud)

Python 代码(不工作):

import base64 
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad

def encrypt(data,key,iv):
        data= pad(data.encode(),16)
        cipher = AES.new(key.encode('utf-8'),AES.MODE_CBC,iv)
        return base64.b64encode(cipher.encrypt(data))

def decrypt(enc,key,iv=None):
        enc = base64.b64decode(enc)
        # enc = enc.encode('utf-8')
        if iv == None:
            cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC)
        else:
            cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv)
        return unpad(cipher.decrypt(enc),16)


with open("demo_file.png.enc", "r+") as fileIn:
    encData = fileIn.read()
    key = "1234567887654321"
    iv = "53509bee-8207-11".encode('utf-8')
    decrypted = decrypt(encData, key, iv)
    

with open("demo_file.png", "wb") as fileOut:
    fileOut.write(decrypted)
Run Code Online (Sandbox Code Playgroud)