简体   繁体   English

错误解密在Android中使用AES / GCM / NoPadding加密的消息

[英]Error decrypting message encrypted using AES/GCM/NoPadding in Android

I'm currently using AES/GCM/NoPadding to perform cipher operations. 我目前正在使用AES / GCM / NoPadding执行加密操作。

My encryption code: 我的加密代码:

fun encrypt(plainText: ByteArray, key: Key): ByteArray? {
        var resultText: ByteArray? = null
        try {
            val cipher = Cipher.getInstance(ALGORITHM)
            cipher.init(Cipher.ENCRYPT_MODE, key)

            val cipherText = cipher.doFinal(plainText)

            resultText = ByteBuffer.allocate(1 + cipher.iv.size + cipherText.size)
                    .put(cipher.iv.size.toByte())
                    .put(cipher.iv)
                    .put(cipherText)
                    .array()
        } catch (e : Exception) {
            Logger.e(TAG, "Error encrypting plain text", e)
        }

        return resultText
    }

My decryption code: 我的解密代码:

fun decrypt(cipherTextWithHeaders: ByteArray, key: Key): ByteArray? {
        var plainText: ByteArray? = null
        try {
            val cipher = Cipher.getInstance(ALGORITHM)

            val ivSize = cipherTextWithHeaders[0].toInt()
            val iv = ByteArray(ivSize)
            System.arraycopy(cipherTextWithHeaders, 1, iv, 0, ivSize)
            cipher.init(Cipher.DECRYPT_MODE, key, GCMParameterSpec(ivSize * 8, iv))

            val headerLen = 1 + ivSize

            val cipherText = ByteArray(cipherTextWithHeaders.size - headerLen)
            System.arraycopy(cipherTextWithHeaders, headerLen, cipherText, 0, cipherTextWithHeaders.size - headerLen)

            plainText = cipher.doFinal(cipherText)
        } catch (e : Exception) {
            Logger.e(TAG, "Error decrypting cipher text", e)
        }

        return plainText
    }

I get this exception while doing doFinal in decrypt method above: 我在上面的解密方法中执行doFinal时遇到此异常:

javax.crypto.IllegalBlockSizeException
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
    at javax.crypto.Cipher.doFinal(Cipher.java:1736)

I tried the below option during encryption: 我在加密期间尝试了以下选项:

val temp = ByteArray(12)
SecureRandom().nextBytes(temp)
cipher.init(Cipher.ENCRYPT_MODE, key, GCMParameterSpec(96, temp))

But this throws the below error: 但这会引发以下错误:

java.security.InvalidAlgorithmParameterException: Caller-provided IV not permitted
    at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:85)
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:265)
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:148)
    at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2659)
    at javax.crypto.Cipher.tryCombinations(Cipher.java:2570)
    at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2475)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:566)
    at javax.crypto.Cipher.init(Cipher.java:973)
    at javax.crypto.Cipher.init(Cipher.java:908)

The GCM auth tag length is not related to the IV length. GCM身份验证标签的长度与IV长度无关。 The standard for AES-GCM is actually 12 -bytes IV and 128 bits GCM tag, see RFC 5288, Section 3 . AES-GCM的标准实际上是12字节IV和128位GCM标签,请参阅RFC 5288,第3节

Example: 例:

String input = "abcdef";

byte[] key = new byte[16];
(new SecureRandom()).nextBytes(key);

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

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"));
byte[] ciphertext = cipher.doFinal(input.getBytes());
byte[] iv = cipher.getIV();
GCMParameterSpec gcmspec = cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
System.out.println("ciphertext: " + ciphertext.length + ", IV: " + iv.length + ", tLen: " + gcmspec.getTLen());

cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(128, iv));
byte[] plaintext = cipher.doFinal(ciphertext);

System.out.println("plaintext : " + new String(plaintext));

Prints: 打印:

ciphertext: 22, IV: 12, tLen: 128
plaintext : abcdef

Try changing GCMParameterSpec(ivSize * 8, iv) to GCMParameterSpec(128, iv) . 尝试将GCMParameterSpec(ivSize * 8, iv)更改为GCMParameterSpec(128, iv)

Though the issue could also be outside, ie the ciphertext could be badly encoded or cut off somewhere. 尽管问题也可能出在外面,即密文可能编码不正确或在某处被切断。 Check cipherText.length . 检查cipherText.length

 java.security.InvalidAlgorithmParameterException: Caller-provided IV not permitted 

That is a limitation of the Android crypto implementation; 这是Android加密实施的局限性; it wants to generate the IV itself during encryption. 它希望在加密期间自行生成IV。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AES / GCM / NoPadding AEADBadTagException - AES/GCM/NoPadding AEADBadTagException 使用“ AES / GCM / NoPadding”在节点中加密文件并在Java中解密。 基本上在node.js中相当于AES / GCM / NoPadding - Encrypt a file in node and decrypt in java using “AES/GCM/NoPadding”. Basically AES/GCM/NoPadding equivalent in node.js 正在寻找用于解密使用 openssl -aes-256-cbc -a -salt 命令加密的消息的 Java 实现? - Looking for Java implementation for decrypting a message encrypted using openssl -aes-256-cbc -a -salt command? 使用AES / GCM / NoPadding的IvParameterSpec和GCMParameterSpec之间的差异 - Difference between IvParameterSpec and GCMParameterSpec with AES/GCM/NoPadding AES/GCM/NoPadding加密JAVA&解密JavaScript - AES/GCM/NoPadding encryption in JAVA & decryption in JavaScript JAVA ANDROID AES CFB填充 - JAVA ANDROID AES CFB NOPADDING 解密使用哈希密钥加密的消息 - Decrypting a message encrypted using a hashed key 在节点 js 中通过 AES/GCM/NoPadding 算法使用密钥和 iv 加密有效负载并在 java 中解密 - Encrypt payload using a key and iv by AES/GCM/NoPadding algorithm in node js and decrypt in java 在PC和Android之间发送加密数据时,AES / CTR / NoPadding最后一块丢失 - AES/CTR/NoPadding last block is lost when sending encrypted data between PC and Android 使用 AES/CFB/NoPadding、AES/OFB/NoPadding 或 AES/CBC/NoPadding 的密码太短 - Password too short using AES/CFB/NoPadding, AES/OFB/NoPadding or AES/ CBC/NoPadding
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM