C#AES解密 - GCM中的mac检查失败

时间:2016-10-02 22:04:43

标签: java c# encryption aes

尝试使用BounceCastle对AES进行数据解密,在GCM中获取mac检查失败错误: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& amp;中的完整代码。 C#。请检查一下。

https://github.com/psraju1/CSharpApplePayDecrypter

3 个答案:

答案 0 :(得分:0)

有同样的问题。请尽量不要哈希商家标识符。它已经哈希了。在设置为partyVInfo之前,忽略它的前两个字节。当您从certifcate获得merchantIdentifier时,有#34;。"在哈希的开头。必须删除

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哈希并删除了商家标识符的前两个字节。现在它有效。

答案 1 :(得分:0)

在听完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;
}

答案 2 :(得分:0)

我遇到了同样的问题,因此我分叉了上面的存储库,进行了必要的更改,将其清理并将其推送到GitHub。

https://github.com/fscopel/CSharpApplePayDecrypter

快乐编码!