提问人:Priya Baweja 提问时间:6/17/2023 最后编辑:Priya Baweja 更新时间:6/17/2023 访问量:128
将 java aes-128-ecb 代码转换为 aes-256-ecb
Convert java aes-128-ecb code to aes-256-ecb
问:
我有 java 代码,它是在 node.js 中模仿 crypto.createCipher() 的 但它是 aes-128-ecb。
byte[] input = jo.toString().getBytes("utf-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
SecretKeySpec skc = new SecretKeySpec(thedigest, "AES/ECB/PKCS5Padding");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skc);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
String query = Base64.encodeToString(cipherText, Base64.DEFAULT);
我想在 java 中将其转换为 aes-256-ecb,因为在节点中使用 crypto.createCipher 中的 aes-256-ecb 算法,我必须在 java 中模仿同样的东西。我尝试将零附加到生成的密钥,但没有帮助请在这里提供帮助
答:
nodejs crypto.createCipher
(和 createDecipher
)使用的密钥派生是 OpenSSL 的,带有 MD5 进行 1 次迭代,没有盐;对于 AES-128-ECB,这只是 B1=MD5(密码),但对于 AES-256-ECB,它是 (B1=MD5(密码)) ||(B2=MD5(B1||密码))。(使用 IV 的模式,即 ECB 以外的模式,将扩展这两种模式。最短的解决方法是将EVP_BytesToKey
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
用类似的东西
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thekey = new byte[32];
md.update(ENCRYPTION_KEY.getBytes("UTF-8"));
md.digest(thekey,0,16); // put B1 in 0..15
md.update(thekey,0,16); md.update(ENCRYPTION_KEY.getBytes("UTF-8"));
md.digest(thekey,16,16); // put B2 in 16..31
然后按照其名称使用。thekey
作为密钥派生函数的自定义实现的替代方法(参见其他答案),您还可以使用加密库的实现,例如 BouncyCastle。EVP_BytesToKey()
EVP_BytesToKey()
优点是您不必担心实现的细节(例如,这有助于更改为带有 IV 的模式,例如 CBC),缺点是额外的依赖关系(以及随之而来的开销):EVP_BytesToKey()
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
...
OpenSSLPBEParametersGenerator pbeGenerator = new OpenSSLPBEParametersGenerator(new MD5Digest()); // digest (here MD5, since createCipher() applies MD5)
pbeGenerator.init(ENCRYPTION_KEY.getBytes(StandardCharsets.UTF_8), new byte[0]); // passphrase; salt (here empty, since createCipher() applies no salt)
ParametersWithIV parameters = (ParametersWithIV) pbeGenerator.generateDerivedParameters(256, 0); // keySize in bits; ivSize in bits (here 0 since ECB doesn't apply an IV)
KeyParameter keyParam = (KeyParameter)parameters.getParameters();
// byte[] iv = parameters.getIV(); // iv (here not required, since ECB doesn't apply an IV)
SecretKeySpec skc = new SecretKeySpec(keyParam.getKey(), "AES");
...
安全:请注意,欧洲央行是不安全的。此外,密钥派生是漏洞(这就是原因,并且已被弃用)。
相反,如有必要,应与可靠的密钥派生函数(例如至少 PBKDF2)结合使用。EVP_BytesToKey()
createCipher()
createDecipher()
createCipheriv()
createDecipheriv()
评论
crypto.createCipher()
crypto.createDecipher()