问题
I'm currently getting an AEADBadTagException when trying to decrypt a file I have encrypted. I have searched pretty much everywhere on stackoverflow and unable to find a solution, and hoping there is just a small mistake I have made or something to do with encoding etc., since GCM is unable to verify the tag that it is generating.
I believe the problem is somewhere in the file I am trying to encrypt/decrypt. The same exact code works on an image, however, when I try to encrypt a PDF, it fails and gives me the above error.
The code below is not using CipherOutputStream/CipherInputStream, but I have tried it with both with no luck.
I understand that it the encryption/decryption methods should not be written like this, especially with the hardcoded IVs, but right now I am just trying to get it to work, then properly securing these methods later.
I am using Android KeyStore to get my secret key. I know this part works since I have lots of other pieces in the app using the Keystore with the same methods. Plus, this methods works with an image.
The error is happening on cipher.doFinal(encryptedBytes). When I use CipherInputStream, it happens on CipherInputStream(EncryptedFileStream, cipher)
Here is the code as well as the error stack, any help is greatly appreciated:
Encryption
val fileBytes = inputStream.readBytes()
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
keyStoreService.checkKeyAndCreate(ALIAS_FILE_KEY)
val key = keyStoreService.getFileKey(ALIAS_FILE_KEY)
val iv = byteArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
cipher.init(Cipher.ENCRYPT_MODE, key, GCMParameterSpec(128, iv))
val encryptedBytes = cipher.doFinal(fileBytes)
outputStream = FileOutputStream(file)
outputStream.write(encryptedBytes)
outputStream.flush()
inputStream.close()
outputStream.close()
Decryption
val encryptedFile = File(filePath)
val encryptedBytes = encryptedFile.readBytes()
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
val key = keyStoreService.getFileKey(ALIAS_FILE_KEY)
val iv = byteArrayOf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
cipher.init(Cipher.DECRYPT_MODE, key, GCMParameterSpec(128, iv))
val decryptedBytes = cipher.doFinal(encryptedBytes)
return ByteArrayInputStream(decryptedBytes)
Stacktrace
E/AndroidRuntime: FATAL EXCEPTION: main
Process: onboard.app.passageways, PID: 15441
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: javax.crypto.AEADBadTagException
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:517)
at javax.crypto.Cipher.doFinal(Cipher.java:2055)
at passageways.android.onboard.services.EncryptionService.readEncryptedFile(EncryptionService.kt:79)
at passageways.android.onboard.fragments.MeetingBookDialogFragment.onViewCreated(Fragment.kt:38)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.security.KeyStoreException: Signature/MAC verification failed
at android.security.KeyStore.getKeyStoreException(KeyStore.java:839)
at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:224)
at android.security.keystore.AndroidKeyStoreAuthenticatedAESCipherSpi$BufferAllOutputUntilDoFinalStreamer.doFinal(AndroidKeyStoreAuthenticatedAESCipherSpi.java:373)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:506)
at javax.crypto.Cipher.doFinal(Cipher.java:2055)
at passageways.android.onboard.services.EncryptionService.readEncryptedFile(EncryptionService.kt:79)
at passageways.android.onboard.fragments.MeetingBookDialogFragment.onViewCreated(Fragment.kt:38)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
回答1:
Turns out readBytes() uses a default buffer size, and only returns a byte buffer that is the length of that. So it was not actually returning me the whole file in bytes, just up to the length of the buffer.
I have switched to using a CipherOutputStream, be sure to include flush() after writing your contents to the tag will be included!
来源:https://stackoverflow.com/questions/53621994/android-javax-crypto-aeadbadtagexception