将 java aes-128-ecb 代码转换为 aes-256-ecb

Convert java aes-128-ecb code to aes-256-ecb

提问人:Priya Baweja 提问时间:6/17/2023 最后编辑:Priya Baweja 更新时间:6/17/2023 访问量:128

问:

我有 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 中模仿同样的东西。我尝试将零附加到生成的密钥,但没有帮助请在这里提供帮助

安全 加密 加密 AES CryptoJS

评论

0赞 Topaco 6/17/2023
直接转换是不可能的,您只能使用 aes-128-ecb 解密并使用 aes-256-ecb 重新加密(顺便说一句,/ 和 ECB 是不安全的)。crypto.createCipher()crypto.createDecipher()
0赞 Priya Baweja 6/17/2023
@Topaco你能检查一下.我提供了更多细节
0赞 Topaco 6/17/2023
啊,好吧,误解了你的第一篇文章。同时,这个问题已经得到了解答。我已经发布了一个替代方案。

答:

0赞 dave_thompson_085 6/17/2023 #1

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

0赞 Topaco 6/17/2023 #2

作为密钥派生函数的自定义实现的替代方法(参见其他答案),您还可以使用加密库的实现,例如 BouncyCastleEVP_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()