I have a AES decrypted ciphertext using openssl and want to decrypt it with java. OpenSSL is not adding the tag automatically at the end, but I'm able to retrieve it. Now I want to understand how the tag is being added in java, just a byte copy is not working
e.g. AES GCM implementation with authentication Tag in Java
OpenSSL result: ciphertext, tag Java: ciphertext = ciphertext/plaintext + tag
My assumption is that the tag in java is added at the end of the plaintext, then comes the mac and then the encryption?!
My issue is raising with inter java provider encrypting/decryption, openssl with openssl and sun with sun is always working!
public static byte[] testData = "Hello World!".getBytes(US_ASCII);
private static int KEY_LENGTH = 32;
private static int KEY_LENGTH_IN_BITS = KEY_LENGTH * 8;
private static int IV_LENGTH = 12;
private static int TAG_LENGTH = 16;
private static int TAG_LENGTH_IN_BITS = TAG_LENGTH * 8;
...
int rc = -1;
String ALGORITHM = "AES_128/GCM/NoPadding";
byte[] key = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 };
byte[] iv = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 };
OPENSSL_EVP_CIPHER_H evp_cipher = OpenSSL.openssl().evp_cipher();
EVP_CIPHER_PTR evp_cipherbyname = evp_cipher.gk_EVP_get_cipherbyname(EVP_CIPHER.EVP_aes_128_gcm);
EVP_CIPHER_CTX_PTR evp_ciper_ctx = evp_cipher.gk_EVP_CIPHER_CTX_new();
rc = evp_cipher.gk_EVP_CipherInit_ex(evp_ciper_ctx, evp_cipherbyname, key, iv, true);
byte[] encryptedData = new byte[testData.length];
rc = evp_cipher.gk_EVP_CipherUpdate(evp_ciper_ctx, encryptedData, 0, testData, 0);
rc = evp_cipher.gk_EVP_CipherFinal_ex(evp_ciper_ctx, encryptedData, 0);
byte[] tag = new byte[TAG_LENGTH];
evp_cipher.gk_EVP_CIPHER_CTX_ctrl(evp_ciper_ctx, EVP.EVP_CTRL_GCM_GET_TAG, tag);
System.out.println("iv: " + Hex.encodeHexString(iv, false));
System.out.println("ciphertext: " + Hex.encodeHexString(encryptedData, false));
System.out.println("tag: " + Hex.encodeHexString(tag, false));
Cipher cipher = Cipher.getInstance(ALGORITHM, "SunJCE");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(TAG_LENGTH_IN_BITS, iv));
byte[] encryptedData2 = cipher.doFinal(testData);
System.out.println("sun encrypted: " + Hex.encodeHexString(encryptedData2, false));
cipher = Cipher.getInstance(ALGORITHM, "SunJCE");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(TAG_LENGTH_IN_BITS, iv));
byte[] encryptedDataWithTag = ByteBuffer.allocate(encryptedData.length + tag.length).put(encryptedData).put(tag)
.array();
byte[] decryptedData = cipher.doFinal(encryptedDataWithTag);
Assert.assertTrue(Arrays.equals(testData, decryptedData));
the resulting error is:
javax.crypto.AEADBadTagException: Tag mismatch!
at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:623)
at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1116)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1053)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)
at test.com.tsystems.gematik.openssl.TestOpenSSLCipher.testGCMEncryptOpenSSLDecryptSun(TestOpenSSLCipher.java:120)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:768)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
iv: 00010203040506070809000102030405
ciphertext: E016003195118774748759D2
tag: A0F69857CB6FD3A0FC289515182BC550
sun encrypted: 9A6E0CA0FDE0A296814CF228BA608612DEC103BCC583FCB0585A9422