【问题标题】:C# AES Decryption - mac check in GCM failedC# AES 解密 - GCM 中的 mac 检查失败
【发布时间】:2016-10-02 22:04:42
【问题描述】:

尝试使用 BounceCastle 对数据进行 AES 解密,在 GCM 中获取 mac check failed 错误:output = cipher.DoFinal(cipherData);

https://github.com/psraju1/CSharpApplePayDecrypter 获取完整代码

错误:

mac check in GCM failed
BouncyCastle.Crypto
   at Org.BouncyCastle.Crypto.Modes.GcmBlockCipher.DoFinal(Byte[] output, Int32 outOff)
   at Org.BouncyCastle.Crypto.BufferedAeadBlockCipher.DoFinal(Byte[] output, Int32 outOff)
   at Org.BouncyCastle.Crypto.BufferedAeadBlockCipher.DoFinal(Byte[] input, Int32 inOff, Int32 inLen)
   at Org.BouncyCastle.Crypto.BufferedCipherBase.DoFinal(Byte[] input)
   at ApplePayDecrypter.ApplePay.DoDecrypt(Byte[] cipherData, Byte[] encryptionKeyBytes) in ApplePayDecrypter.cs:line 107

代码:

protected byte[] RestoreSymmertricKey(byte[] sharedSecretBytes)
{
    byte[] merchantIdentifier = GetHashSha256Bytes("");//applePayRequest.MerchantIdentifier);

    ConcatenationKdfGenerator generator = new ConcatenationKdfGenerator(new Sha256Digest());
    byte[] COUNTER = { 0x00, 0x00, 0x00, 0x01 };
    byte[] algorithmIdBytes = Encoding.UTF8.GetBytes((char)0x0d + "id-aes256-GCM");
    byte[] partyUInfoBytes = Encoding.UTF8.GetBytes("Apple");
    byte[] partyVInfoBytes = merchantIdentifier;
    byte[] otherInfoBytes = Combine(Combine(algorithmIdBytes, partyUInfoBytes), COUNTER);//, partyVInfoBytes);

    generator.Init(new KdfParameters(sharedSecretBytes, otherInfoBytes));
    byte[] encryptionKeyBytes = new byte[16];
    generator.GenerateBytes(encryptionKeyBytes, 0, encryptionKeyBytes.Length);
    return encryptionKeyBytes;
}

private byte[] DoDecrypt(byte[] cipherData, byte[] encryptionKeyBytes)
{
    byte[] output;
    try
    {
        KeyParameter keyparam = ParameterUtilities.CreateKeyParameter("AES", encryptionKeyBytes);
        ParametersWithIV parameters = new ParametersWithIV(keyparam, symmetricIv);
        IBufferedCipher cipher = GetCipher();
        cipher.Init(false, parameters);
        try
        {
            output = cipher.DoFinal(cipherData);
        }
        catch (Exception ex)
        {
            throw new ApplicationException("Invalid Data");
        }
    }
    catch (Exception ex)
    {
        throw new ApplicationException("There was an error occured when decrypting message.");
    }

    return output;
}

public IBufferedCipher GetCipher()
{
    return CipherUtilities.GetCipher("AES/GCM/NoPadding");
}



private static byte[] GetHashSha256Bytes(string text)
{
    byte[] bytes = Encoding.UTF8.GetBytes(text);
    SHA256Managed hashstring = new SHA256Managed();
    byte[] hash = hashstring.ComputeHash(bytes);
    return hash;
}

protected static byte[] Combine(byte[] first, byte[] second)
{
    byte[] ret = new byte[first.Length + second.Length];
    Buffer.BlockCopy(first, 0, ret, 0, first.Length);
    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
    return ret;
}

实际上,我正在尝试为 ApplePay 解密,并将示例 Java 代码转换为 C#。如果你想看一下 JAVA 代码,请告诉我

这是 JAVA 和 C# 的完整代码。请检查一下。

https://github.com/psraju1/CSharpApplePayDecrypter

【问题讨论】:

标签: java c# encryption aes


【解决方案1】:

有同样的问题。请尽量不要对商家标识符进行哈希处理。它已经被散列了。并在设置为partyVInfo 之前忽略它的前两个字节。当您从证书中获取商家标识符时,哈希的开头有“.@”。必须删除

byte[] partyVInfo = ExtractMIdentifier();

private byte[] ExtractMIdentifier()
{
    X509Certificate2 merchantCertificate = InflateCertificate();
    byte[] merchantIdentifierTlv = merchantCertificate.Extensions["1.2.840.113635.100.6.32"].RawData;
    byte[] merchantIdentifier = new byte[64];

    Buffer.BlockCopy(merchantIdentifierTlv, 2, merchantIdentifier, 0, 64);

    return Hex.Decode(Encoding.ASCII.GetString(merchantIdentifier));
}

第五方信息 商家标识符的 SHA-256 哈希。该值是一个固定长度的位串。

我不使用 SHA-256 哈希并删除了商家标识符的前两个字节。现在可以了。

【讨论】:

    【解决方案2】:

    在听从 Lou 的建议后,我需要再做两处更改才能使其正常工作。

    • 我摆脱了 COUNTER 并使用了partyVInfoByes
    • 我将 encryptionKeyBytes 更改为 32 字节而不是 16 字节的数组,因为它是 256 位 ECC (32 * 8 = 256)

    RestoreSymmetricKey 现在看起来像这样:

    protected byte[] RestoreSymmertricKey(byte[] sharedSecretBytes)
    {
        byte[] merchantIdentifier = ExtractMIdentifier();
    
        ConcatenationKdfGenerator generator = new ConcatenationKdfGenerator(new Sha256Digest());
        byte[] algorithmIdBytes = Encoding.UTF8.GetBytes((char)0x0d + "id-aes256-GCM");
        byte[] partyUInfoBytes = Encoding.UTF8.GetBytes("Apple");
        byte[] partyVInfoBytes = merchantIdentifier;
        byte[] otherInfoBytes = Combine(Combine(algorithmIdBytes, partyUInfoBytes), partyVInfoBytes);
    
        generator.Init(new KdfParameters(sharedSecretBytes, otherInfoBytes));
        byte[] encryptionKeyBytes = new byte[32];
        generator.GenerateBytes(encryptionKeyBytes, 0, encryptionKeyBytes.Length);
        return encryptionKeyBytes;
    }
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,所以我分叉了上面的 repo,进行了必要的更改,清理并推送到 GitHub。

      https://github.com/fscopel/CSharpApplePayDecrypter

      编码愉快!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-08
        • 1970-01-01
        • 2021-05-29
        • 2015-02-08
        • 2023-01-31
        • 2016-06-04
        • 2019-01-31
        • 2019-11-14
        相关资源
        最近更新 更多