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

使用SHA-256哈希算法的带有PSS填充和MGF1掩码的C#RSA签名

彭展
2023-03-14

首先,我对加密/签名还是新手,所以请容忍任何滥用术语的行为。

我需要在C#中创建一个签名,该签名将被Python库验证。在Python中,解码/验证签名只需一段简单的代码:

    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import padding

    public_key.verify(signature, payload_contents,
                      padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                  salt_length=padding.PSS.MAX_LENGTH,
                                  ), hashes.SHA256(), )

我当前的C#代码如下所示:

    private static string CreateSignature(byte[] data, string privateKeyFileLocation)
    {
        var cert = new X509Certificate2(privateKeyFileLocation);
        
        byte[] signedBytes;
        using (var rsa = cert.GetRSAPrivateKey())
        {
            signedBytes = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
        }
        var finalString = Convert.ToBase64String(signedBytes);
        return finalString;
    }

但是,签名在Python代码中未通过验证检查。它看起来像PSS填充。Net库默认使用MGF1。然而,我相信我有问题,因为掩码生成函数(MGF1)在Python代码中使用256位哈希,但在C#中默认为SHA1。我已经趟过了。Net C#留档,看起来没有办法覆盖它。我研究了充气城堡的C#留档,只是很难找到任何类似的例子来设置自定义参数的填充。有没有人有这方面的经验,可以给点提示?

共有1个答案

解晟睿
2023-03-14

只是为了其他处理这件事的人。这是我最后得到的代码。

    private static string GenerateSignatureForData(string data, string privateKeyFileLocation)
    {
        var cert = new X509Certificate2(privateKeyFileLocation, "12345", X509KeyStorageFlags.Exportable);
        var bcCert = TransformRSAPrivateKey(cert.PrivateKey);
        var keyLen = (int)Math.Ceiling((cert.GetRSAPrivateKey().KeySize - 1) / 8.0);

        byte[] signedBytes = CreateSignature(Encoding.ASCII.GetBytes(data), bcCert, keyLen);
        return Convert.ToBase64String(signedBytes);
    }

    private static AsymmetricKeyParameter TransformRSAPrivateKey(AsymmetricAlgorithm privateKey)
    {
        RSACryptoServiceProvider prov = privateKey as RSACryptoServiceProvider;
        RSAParameters parameters = prov.ExportParameters(true);

        return new RsaPrivateCrtKeyParameters(
            new BigInteger(1, parameters.Modulus),
            new BigInteger(1, parameters.Exponent),
            new BigInteger(1, parameters.D),
            new BigInteger(1, parameters.P),
            new BigInteger(1, parameters.Q),
            new BigInteger(1, parameters.DP),
            new BigInteger(1, parameters.DQ),
            new BigInteger(1, parameters.InverseQ));
    }

    private static byte[] CreateSignature(byte[] data, AsymmetricKeyParameter privateKey, int keyLength)
    {
        var digest = new Sha256Digest();
        var saltLength = keyLength - digest.GetDigestSize() - 2;

        PssSigner signer = new PssSigner(new RsaEngine(), new Sha256Digest(), digest, saltLength);
        signer.Init(true, new ParametersWithRandom((RsaPrivateCrtKeyParameters)privateKey));
        signer.BlockUpdate(data, 0, data.Length);
        return signer.GenerateSignature();
    }

还有一些额外的,因为盐的长度也需要计算。我必须查看crypto库的源代码,以计算python代码中指示的salt MAX_长度:

    salt_length=padding.PSS.MAX_LENGTH

以下是严格执行此操作所需的代码:

    var cert = new X509Certificate2(privateKeyFileLocation, "12345", X509KeyStorageFlags.Exportable);
    var bcCert = TransformRSAPrivateKey(cert.PrivateKey);
    var keyLen = (int)Math.Ceiling((cert.GetRSAPrivateKey().KeySize - 1) / 8.0);
    var digest = new Sha256Digest();
    var saltLength = keyLength - digest.GetDigestSize() - 2;

类似地,转换。Net Crypto lib非对称性算法到Bouncy Castle非对称性KeyParameter需要上面看到的转换函数TransformRSAPrivate ateKey。

 类似资料:
  • 我正在尝试使用亚马逊的弹性代码转换器。这里我需要sha-256散列一个字符串;http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 我已经尝试了我在网上找到的任何方法,但我找不到与页面和一些在线哈希网站提供的相同的结果。 下面是要散列的字符串,您可以从上面的链接中找到; 以下是预期结果: 3

  • 问题内容: 我在Oracle的Java标准加密提供程序中发现了困难的方法 使用以SHA-1实例化的MFG1;SHA-256仅用于对标签进行哈希处理(实际上是空的)。我发现在MFG1中实际使用SHA-256的唯一解决方案(得到该答案和注释的帮助)是使用以下替代形式Cipher.init: 问:有没有转变是会认识到,与类似的效果,除了与MGF1使用SHA-256? 问题答案: 不,没有。 Java是开

  • 我通常会在这里找到我们大部分问题的答案,但这次我需要问:-)。 我们在Android 8.0(API级别26)上运行的一个应用程序中遇到了RSA加密/解密问题。 我们一直在将RSA与“RSA/ECB/OAEPWithSHA-256AndMGF1Padding”一起使用,这在Android 7.1之前的所有版本上都能正常工作。在Android 8.0上运行的同一代码在调用Cipher时引发了非法Bl

  • 我想分两步使用RSA/PSS签名制作SHA256,首先散列一条消息,然后使用RSASSA-PSS签名摘要 但我使用SHA256时RSA/PSS无法验证 我需要一些帮助,谢谢你的帮助。

  • 问题内容: 我需要计算大文件(或其一部分)的SHA-256哈希。我的实现工作正常,但比C 的CryptoPP计算要慢得多(25分钟vs. 30 GB文件的10分钟)。我需要的是在C 和Java中执行时间相似,因此散列几乎可以同时准备好。我也尝试了Bouncy Castle的实现,但是它给了我相同的结果。这是我如何计算哈希值: 问题答案: 我的解释可能无法解决您的问题,因为它很大程度上取决于您的实际

  • 因此,我试图找出如何在ios上进行hmacshad256哈希,因为这是我为wcf服务api所做的哈希。我一直试图寻找一些关于它的信息,但通常只是最终得到一个SHA-256哈希。