Priya Baweja
Priya Baweja

Reputation: 19

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

am having the java code which is the mimicing crypto.createCipher() in node.js But it is with 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);

I want to convert the same to aes-256-ecb in java because in node am using aes-256-ecb algo in crypto.createCipher and I have to mimic same thing in java.I tried appending zeros to generated key but didn't help Please help here

Upvotes: 0

Views: 211

Answers (2)

Topaco
Topaco

Reputation: 49460

As an alternative to a custom implementation of the key derivation function EVP_BytesToKey() (see the other answer) you can also use an EVP_BytesToKey() implementation of a crypto library, e.g. BouncyCastle.

The advantage is that you don't have to worry about the details of the implementation of EVP_BytesToKey() (this e.g. facilitates the change to a mode with IV such as CBC), the disadvantage is an additional dependency (and the overhead that comes with it):

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");
...

Security: Note that ECB is insecure. Also the key derivation with EVP_BytesToKey() is a vulnerability (which is why createCipher() and createDecipher() are deprecated).
Instead, createCipheriv() and createDecipheriv() should be used if necessary in conjunction with a reliable key derivation function such as at least PBKDF2.

Upvotes: 0

dave_thompson_085
dave_thompson_085

Reputation: 39010

The key derivation used by nodejs crypto.createCipher (and createDecipher) is OpenSSL's EVP_BytesToKey with MD5 for 1 iteration and no salt; for AES-128-ECB this is simply B1=MD5(password) but for AES-256-ECB it is (B1=MD5(password)) || (B2=MD5(B1||password)) . (Modes using an IV, i.e. other than ECB, would extend both of these.) The shortest fix is to replace

                    MessageDigest md = MessageDigest.getInstance("MD5");
                    byte[] thedigest = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));

with something like

                    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

and then use thekey as its name indicates.

Upvotes: 0

Related Questions