对接 C++ 某加解密接口
1 2 3 4 5 #define KEY "01234567890123456789012345678901" EVP_aes_128_cfb128()
AES is based on a design principle known as a substitution–permutation network, and is efficient in both software and hardware.[9] Unlike its predecessor DES, AES does not use a Feistel network. AES is a variant of Rijndael, with a fixed block size of 128 bits, and a key size of 128, 192, or 256 bits. By contrast, Rijndael per se is specified with block and key sizes that may be any multiple of 32 bits, with a minimum of 128 and a maximum of 256 bits.
–维基百科 - AES
根据维基百科里的说法,AES 的 key size 只支持 128 bits, 192 bits, 256 bits
KEY 字符串长度
key size
16
128 bits
24
192 bits
32
256 bits
对方提供的对接接口中的 KEY 的长度是 32 理应对应 aes-256 却调用了 aes-128,实际只利用了前 16 个字符,因为本身 32 大于 16 调用 aes-128 的时候会只读前面的 16,而且能读到,便没有报错。
对接接口么,一般就直接把 KEY 复制过来传进去了,但在其他语言中越是封装好的库,越有一些自动的操作,比如,根据 KEY 的长度,自动选择 aes-128 还是 aes-256,因为传的 KEY 是 32 个字符,底层库自动选择了 aes-256,怎么测试,结果都对不上,属实郁闷。
在 Python 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import base64from Crypto.Cipher import AESkey: bytes = '01234567890123456789012345678901' [:16 ].encode('utf-8' ) iv: bytes = '0123456789012345' .encode('utf-8' ) def encrypt (content: bytes) -> bytes: """ 加密内容 :param content: 要被加密的数据 :return: 加密后的数据 """ aes = AES.new(key, AES.MODE_CFB, iv, segment_size=128 ) return aes.encrypt(content) if __name__ == '__main__' : content: bytes = 'lixifun' .encode('utf-8' ) base64.b64encode(encrypt(content))
如要在 windows 下运行,需要 pip install pycryptodome 。
在 Java 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import org.junit.jupiter.api.Test;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.nio.charset.StandardCharsets;import java.util.Base64;public class AesCfbTest { private static final byte [] KEY = "01234567890123456789012345678901" .getBytes(StandardCharsets.UTF_8); private static final byte [] KEY = "01234567890123456789012345678901" .substring(0 , 16 ) .getBytes(StandardCharsets.UTF_8); private static final byte [] IV = "0123456789012345" .getBytes(StandardCharsets.UTF_8); @Test void encryptTest () { byte [] content = "lixifun" .getBytes(StandardCharsets.UTF_8); byte [] res = encrypt(content); System.out.println(new String(Base64.getEncoder().encode(res))); } public static byte [] encrypt(byte [] content) { try { Cipher aseCfb = Cipher.getInstance("AES/CFB/NoPadding" ); SecretKeySpec keySpec = new SecretKeySpec(KEY, 0 , 16 , "AES" ); IvParameterSpec ivSpec = new IvParameterSpec(IV); aseCfb.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); return aseCfb.doFinal(content); } catch (Exception e) { e.printStackTrace(); } return null ; } }
参考