Reputation: 19
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
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
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