使用BountyCastle .NET的AES256解密失败,并显示“ GCM中的Mac检查失败”

时间:2019-04-16 15:44:36

标签: .net bouncycastle aes-gcm

我正在使用BountyCastle.NetCore NuGet库从我们的服务器解密已经准备好的加密消息。我能够成功使用Java密码库(本机)和Python(pycrptodome)实现。通常,我们的服务器正在按照以下方式准备消息:

enter image description here

解密策略是:

  • 通过base64解码来准备AES-256密钥 cryptographyKey。

  • 通过base64解码消息正文来准备密文字节。

  • 从密文中删除标签。
  • 通过复制密文的前16个字节来准备AAD。
  • 通过从AAD复制4-16字节来准备NONCE(IV)。
  • 然后使用AES – GCM解密,标签长度= 16个字节;用输入
    从1、3、4、5开始。

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

注意:我没有在下面的代码中应用代码,因为这更多是验证步骤,而且我无法解密邮件。

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检查失败”。

任何其他建议都将受到欢迎:-)

0 个答案:

没有答案