首页 > 解决方案 > 使用带有 BountyCastle .NET 的 AES256 解密失败并显示“mac check in GCM failed”

问题描述

我正在使用BountyCastle.NetCore NuGet 库从我们的服务器解密已经准备好的加密消息。我能够成功使用 Java 加密库(本机)和 Python(pycrptodome)实现。一般来说,我们的服务器正在准备这样的消息:

在此处输入图像描述

解密策略是:

应用基于此示例的通用算法,我的实现如下所示:

注意:我没有在下面的代码中应用标签,因为它更像是一个验证步骤,我无法通过解密消息。

public string Decrypt(string cryptoKey, string cypherText)
{
    string sR = string.Empty;
    try
    {
        // Prepare the AES-256 secret key by decoding the cryptographyKey
        var keyBytes = Convert.FromBase64String(cryptoKey);

        // Prepare the Cypher bytes by decoding the cypher text
        var cypherBytes = Convert.FromBase64String(cypherText);

        // <------AAD----->
        // [---][--NONCE--][-----Encrypted Message-----][---TAG---]
        // <-------------------CypherText------------------------->

        // Prepare the AAD - first AAD_LENGTH from cypher
        var aad = new Byte[AAD_LENGTH];
        Array.Copy(cypherBytes, 0, aad, 0, AAD_LENGTH);

        // Prepare NONCE - bytes 4-16 from AAD
        var nonce = new Byte[NONCE_LENGTH];
        Array.Copy(aad, AAD_LENGTH - NONCE_LENGTH, nonce, 0, NONCE_LENGTH);

        // Extract the encrypted message within the body - between AAD and TAG section
        var encryptedMsgSize = cypherBytes.Length - TAG_LENGTH - AAD_LENGTH;
        var encryptedMsg = new Byte[encryptedMsgSize];
        Array.Copy(cypherBytes, AAD_LENGTH, encryptedMsg, 0, encryptedMsgSize);

        GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine());
        AeadParameters parameters = new AeadParameters(new KeyParameter(keyBytes), 128, nonce);

        cipher.Init(false, parameters);
        cipher.ProcessAadBytes(cypherBytes, 0, AAD_LENGTH);

        byte[] plainBytes = new byte[cipher.GetOutputSize(encryptedMsg.Length)];
        Int32 retLen = cipher.ProcessBytes(encryptedMsg, 0, encryptedMsg.Length, plainBytes, 0);
        cipher.DoFinal(plainBytes, retLen);

        sR = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n\0".ToCharArray());
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }

    return sR;
}

尽管尝试了许多不同的组合,设置不同的参数等,它总是会抛出异常:

cipher.DoFinal(plainBytes, retLen);

“在 GCM 中的 mac 检查失败”。

欢迎任何其他建议:-)

标签: .netbouncycastleaes-gcm

解决方案


推荐阅读