当前位置: 首页 > 知识库问答 >
问题:

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

欧阳子石
2023-03-14
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
    }
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
    }
javax.crypto.IllegalBlockSizeException
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:519)
    at javax.crypto.Cipher.doFinal(Cipher.java:1736)

我在加密过程中尝试了以下选项:

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

但这会引发以下错误:

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)

共有1个答案

夏和雅
2023-03-14

GCM auth标签长度与IV长度无关。AES-GCM的标准实际上是12-bytes IV和128bits GCM标记,请参见RFC 5288第3节。

示例:

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));

印花:

ciphertext: 22, IV: 12, tLen: 128
plaintext : abcdef
java.security.InvalidAlgorithmParameterException: Caller-provided IV not permitted
 类似资料:
  • 我使用AES方法对从txt文件调用的sentance进行加密。我使用了GCM模式并创建了一个特定的密钥。一切都在工作(代码如下)。 我尝试实现解密过程,也就是说,我只有密钥(HexMyKeyvalue)和加密消息(HexEncryptedOriginalMessage value)并且我想对其进行解密。但问题是我错过了一些东西... 我写了下面的代码,但我有错误消息。 TypeError:decr

  • 以下是我的加密/解密方法: 所以现在当我尝试加密时,我得到了这个异常: 我已经尝试在encrypt和Decrpt中使用密码实例。它只用于加密而不用于解密。我认为需要填充,因为数据大小不是16字节的倍数。“data”字节长度打印为,因此尝试将字符附加到数据中,然后进行加密,但也不起作用。

  • 我正在使用一个带有NFC的微控制器,所以我需要发送加密数据,为什么我使用AES/CBC/NOPADDING而我正在处理android应用程序,我有一个加密和解密的问题,这是我正在处理的代码 这是我的日志:-d/data ;after ;encode:-:zjsew6h+abzfkwna/pqpdzumnfhy0kmz2lxf23tdavim1c5l5oimagwxg6nrt0udciy/xeaeh

  • 我试图在Android和PHP端使用AES加密/解密数据,并累犯空答案。 首先,我在Android中生成了对称密钥: 在服务器端,我试图解密数据。我可以解密(从RSA)秘密的AES密钥,并得到它的字符串表示。在客户端(Android)和服务器端(PHP)上是一样的。但是如何使用这个字符串AES密钥来解密数据呢?我尝试了这个(PHP): PHP中的结果: 怎么啦?