1

I have encrypted a file by using OpenSSL aes-256-gcm. As aes-256-gcm not directed supported by command line I have installed LibreSSL and I am able to use the below command to encrypt the data of a file.

openssl enc -aes-256-gcm -K 61616161616161616161616161616161 -iv 768A5C31A97D5FE9 -e -in file.in -out file.out

I need to decrypt the data of file.out in Java and I am unable to do that.

Sample code :

    // Get Cipher Instance
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

    String key = "61616161616161616161616161616161";
    byte[] IV = "768A5C31A97D5FE9".getBytes();

    // Create SecretKeySpec
    SecretKeySpec keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

    // Create GCMParameterSpec
    GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, IV);

    // Initialize Cipher for DECRYPT_MODE
    cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);

    // Perform Decryption
    byte[] decryptedText = cipher.doFinal(cipherText); // for the data by reading file.out

However, I am getting an exception saying javax.crypto.AEADBadTagException: Tag mismatch!

1 Answer 1

3

That should't work. Commandline openssl enc doesn't support AEAD ciphers/modes, although early versions of 1.0.1 (below patch h, in 2012-2014) failed to catch if you incorrectly specified such a cipher and silently produced wrong output. If you are actually using LibreSSL and not OpenSSL, it appears to have inherited this problem and not fixed it, even though the whole point of the LibreSSL project was that they were going to fix all the bugs caused by the incompetent OpenSSL people.

If this were a cipher that worked correctly in OpenSSL (and also Java), like aes-256-ctr, then your only problem would be that openssl enc -K -iv take their arguments in hex (suitable for a shell context), whereas Java crypto is called from code that can handle binary data and expects its arguments in that form. As a result the values you provide to OpenSSL are actually 16 bytes (128 bits) and 8 bytes (64 bits), not 256 bits and 128 bits as they should be (for CTR; for GCM an IV of 96 bits would be correct, but as noted GCM won't work here). openssl enc automatically pads -K -iv with (binary) zeros, but Java doesn't. Thus you would need something more like

 byte[] key = Arrays.copyOf( javax.xml.bind.DatatypeConverter.parseHexBinary("61616161616161616161616161616161"), 32);
 // Arrays.copyOf zero-pads when expanding an array
 // then use SecretKeySpec (key, "AES")
 // and IVParameterSpec (iv) instead of GCMParameterSpec

 // but after Java8 most of javax.xml is removed, so unless you
 // are using a library that contains this (e.g. Apache) 
 // or have already written your own, you need something like

 byte[] fromHex(String h){
   byte[] v = new byte[h.length()/2];
   for( int i = 0; i < h.length(); i += 2 ) v[i] = Integer.parseInt(h.substring(i,i+2),16);
   return v;
 }

Compare AES encrypt with openssl command line tool, and decrypt in Java and Blowfish encrypt in Java/Scala and decrypt in bash (the latter is the reverse direction, but the need to match is the same)

3
  • I am using OpenSSL version of OpenSSL 1.1.1c and by using LibreSSL I am able encrypt and decrypt using the below command. openssl enc -aes-256-gcm -nopad -K 61616161616161616161616161616161 -iv 768A5C31A97D5FE9 -e -in file.in -out file13.out openssl enc -d -aes-256-gcm -nopad -K 61616161616161616161616161616161 -iv 768A5C31A97D5FE9 -e -in file13.out -out file113.in And I am using CBC mode I am able to encrypt by openssl command and decrypt in Java. I think I am doing something wrong for GCM mode. Commented Mar 23, 2020 at 7:45
  • @subratpadhi - LibreSSL seems to ignore the authentication tag on AES-GCM, here, which is actually a bug. Since this applies to both encryption and decryption, both work within LibreSSL. However, cross platform (e.g. with Java) decryption fails (even if key and IV are passed properly so that they are identical on both sides) because the tag is mandatory for authentication.
    – Topaco
    Commented Mar 23, 2020 at 10:03
  • Can we do AES GCM decryption by bypassing the authentication tag on the Java side? Commented Mar 23, 2020 at 12:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.