在Java中使用 "AESCFBNoPadding "加密和在Python中使用AES.MODE_CFB解密会产生不同的结果。

问题描述 投票:0回答:0

在Java中,下面的代码可以对任意长度的字符串进行加密,并顺利解密。

Java代码。

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class AesEncryption {
    public static void main(String[] args) throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchPaddingException {
        AesEncryption ae = new AesEncryption();
        byte[] secret = ae.encrypt("Hello World!");
        for (byte b : secret)
            System.out.print(String.format("%d, ", b));
        System.out.print("\n");
        System.out.print(String.format("%s\n", ae.decrypt(secret)));
    }

    private final IvParameterSpec iv;
    private final SecretKeySpec keySpec;

    public AesEncryption() throws NoSuchAlgorithmException {
        byte[] key = "thisisasecretkey".getBytes(StandardCharsets.UTF_8);
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(key);
        this.iv = new IvParameterSpec(md.digest());
        this.keySpec = new SecretKeySpec(key, "AES");
    }

    public byte[] encrypt(String content) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, this.keySpec, this.iv);
        return cipher.doFinal(content.getBytes());
    }

    public String decrypt(byte[] secret) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, this.keySpec, this.iv);
        return new String(cipher.doFinal(secret));
    }
}

Python代码:

import array
import hashlib
from Crypto.Cipher import AES

Class AesEncryption:
    def __init__(self):
        key = 'thisisasecretkey'.encode('UTF-8')
        md = hashlib.md5()
        md.update(key)
        iv = md.digest()
        self.__cryptor = AES.new(key, AES.MODE_CFB, iv, segment_size=128)

    def encrypt(self, content):
        return self.__cryptor.encrypt(AesEncryption.r_pad(content.encode('UTF-8')))[:len(content.encode('UTF-8'))]

    def decrypt(self, secret):
        return self.__cryptor.decrypt(secret)

    @staticmethod
    def r_pad(payload):
        length = 16 - (len(payload) % 16)
        return payload + (chr(length) * length).encode('UTF-8')


if __name__ == '__main__':
    secretstr = array.array('B', [-108, 20, -91, -103, 13, 59, 94, -51, 17, -104, -30, -83]).tostring()
    ae = AesEncryption()
    print(ae.decrypt(secretstr).decode('UTF-8'))

但是当我把Java代码产生的秘密字节数组传给PyCrypto时 解密失败了 Python代码使用的是 AES.MODE_CFBsegment_size = 128 来匹配Java中的AES模式,但纯文本的长度不符合16字节块的要求。改变 segment_size 也不会产生同样的结果。所以我想 NoPadding 可能是问题所在。的算法是什么?AES/CFB/NoPadding 模式在Java中的应用?它与PyCrypto中使用的算法又有什么不同?谢谢。

java python encryption aes
© www.soinside.com 2019 - 2024. All rights reserved.