【问题标题】:RSA Signing with PHP and verifying with C#使用 PHP 进行 RSA 签名并使用 C# 进行验证
【发布时间】:2012-03-09 11:20:11
【问题描述】:

我正在构建一个基于客户端 (C#) 和服务器 (PHP) 的应用程序。

我想使用 RSA-SHA1 对服务器上的数据进行签名并发送给客户端。

在服务器上,即 PHP 我使用 PHPSecLib,使用私钥签名。 在客户端,即 C# 上,我使用的是 RSACryptoServiceProvider。 来自服务器的签名哈希与客户端不匹配。我提供 C# 和 PHP 代码:

PHP #输出

BLkgXU6t6IYNdlrgTaJgaGzZtSc9NjY9q67PbidGo0e79SyQ7b18uKSg1a215r583atzIlFYkAyxDCjvQJIBATdeOKpWuzdtRkZqDX7TQAw5jLHdsFjL3lQWABERFUdEs9XuCykb3I8UNVT2UgmMRZ3pyKknCMdc5AlE9mKXOYI=

PHP 代码

$plaintext = 'O';
$rsa = new Crypt_RSA();
$rsa->loadKey("<RSAKeyValue><Modulus>3BqiIB3ouyXHDMpW43TlZrx8fkts2FVVARJKNXFRQ/WIlsthDzL2jY2KEJVN6BKE4A51X+8LMzAI+2z3vIgAQT3bRSfOwygpGBjdhhnXJwFlQ6Gf/+z0ffQfVx/DHw3+QWphcwGDBst+KIA6u6ayy+RDE+jEityyyWDiWqkR9J8=</Modulus><Exponent>AQAB</Exponent><P>8a8nuVhIANh7J2TLn4wWTXhZY1tvlyFKaslOeAOVr+wgEWLQpLZ0Jpjm8aUyyOYPXlk7xrA5BOebtz41diu4RQ==</P><Q>6SQ9y3sEMjrf/c4bHGVlhOj4LUVykradWWUNC0ya7llnR8y1djJ1uUut+EoAa1JQCGukuv4K8NvN1Ieo72Fhkw==</Q><DP>cg0VMusNN5DxNRrk2IrUL4TesfuBQpGMO6554DrY1acZTvsRuNj9IQXA3kH2IEYo9H4prk6U6dKeci/iLLze/Q==</DP><DQ>m/pZNXeZ+RkWnrFzxe24m9FZqMAbxThT0Wkf7v1Tcj9yL8EvbmKYDF4riD/KRAMP9HJABbLNExObg6M3TOAz7Q==</DQ><InverseQ>w8PvW8srrPCuOcphBKXSyoZxCZn81+rovBxuE8AB95m5X+URE8SunK7f+g7hBBin6nUOaVGohBP8jzkQEsdx1Q==</InverseQ>  <D>AsVPDypxOJHkLJQLffeFv8JVqt1WNG72j/nj90JC7KEVpBhRU3inw+ZpO4Y1odtB0vQ7pAaFVJKhOlEH2Va48hNUEQujML8rE+LZXgI3lu0TlqOCIqTHIljeJry0ca30XFtFDp9kh0Kr/0CgGMqgIed+hDUjAad8ke9D2YicDok=</D></RSAKeyValue>",2);//2 for Pivate Key XML
$signature = $rsa->sign($plaintext); 
echo base64_encode($signature);

C# 输出

aCqhRe/lj99Yv0cLVxZD9v0M29qiEhlNOTIGuVuUbw58sp/9lLQEoMqKQrIfyTA7O2OIw5QWV9eZXlAlOlvvBPR1IOahk3mr8N8xaT5+T2fG5cEldeOWwKKxSNHqEBzIVT/4FQqlpvrmtoHJIL6n6KjDb/HQD2kgmMLmQffVYGo=

C#代码

string private_xml = @"<RSAKeyValue><Modulus>3BqiIB3ouyXHDMpW43TlZrx8fkts2FVVARJKNXFRQ/WIlsthDzL2jY2KEJVN6BKE4A51X+8LMzAI+2z3vIgAQT3bRSfOwygpGBjdhhnXJwFlQ6Gf/+z0ffQfVx/DHw3+QWphcwGDBst+KIA6u6ayy+RDE+jEityyyWDiWqkR9J8=</Modulus><Exponent>AQAB</Exponent><P>8a8nuVhIANh7J2TLn4wWTXhZY1tvlyFKaslOeAOVr+wgEWLQpLZ0Jpjm8aUyyOYPXlk7xrA5BOebtz41diu4RQ==</P><Q>6SQ9y3sEMjrf/c4bHGVlhOj4LUVykradWWUNC0ya7llnR8y1djJ1uUut+EoAa1JQCGukuv4K8NvN1Ieo72Fhkw==</Q><DP>cg0VMusNN5DxNRrk2IrUL4TesfuBQpGMO6554DrY1acZTvsRuNj9IQXA3kH2IEYo9H4prk6U6dKeci/iLLze/Q==</DP><DQ>m/pZNXeZ+RkWnrFzxe24m9FZqMAbxThT0Wkf7v1Tcj9yL8EvbmKYDF4riD/KRAMP9HJABbLNExObg6M3TOAz7Q==</DQ><InverseQ>w8PvW8srrPCuOcphBKXSyoZxCZn81+rovBxuE8AB95m5X+URE8SunK7f+g7hBBin6nUOaVGohBP8jzkQEsdx1Q==</InverseQ>  <D>AsVPDypxOJHkLJQLffeFv8JVqt1WNG72j/nj90JC7KEVpBhRU3inw+ZpO4Y1odtB0vQ7pAaFVJKhOlEH2Va48hNUEQujML8rE+LZXgI3lu0TlqOCIqTHIljeJry0ca30XFtFDp9kh0Kr/0CgGMqgIed+hDUjAad8ke9D2YicDok=</D></RSAKeyValue>";


            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(private_xml);
            string Text = "O";
            byte[] Data = Encoding.ASCII.GetBytes(Text);

            byte[] signature = rsa.SignData(Data, new SHA1CryptoServiceProvider());
            string o = Convert.ToBase64String(signature);

【问题讨论】:

  • PHP 没有我假设的 rsa.FromXMLString 接口。尝试标准化的值。
  • PhpSecLib 支持 XML。 rsa.FromXMLString() 是 C# 代码
  • 对,刚刚看到,您使用的是CRYPT_RSA_PRIVATE_FORMAT_XML

标签: c# php rsa


【解决方案1】:

也许这个扩展方法会有所帮助:

    /// <summary>
    /// Generates a (SHA1) hashed string, by using the passphrase as a poor man's salt.
    /// </summary>
    public static string RenderHash(this string value, string passPhrase)
    {
        // Append the passphrase to the value
        value += passPhrase;

        // Convert the string value to a byte array 
        // Note: I've used the UTF8 encoding here
        byte[] buffer = Encoding.UTF8.GetBytes(value);

        // And automagically convert it to a hashed string
        SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
        string hash = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");

        return hash;
    }

(来源:https://gist.github.com/1959763

在这种情况下passPharse 参数是可选的。这是如果您想在其中添加某种盐。此外,请务必注意空格和换行符 (CRLF)。

【讨论】:

  • 我想在客户端使用公钥进行验证。
【解决方案2】:

PhpSecLib 和 C# RSA 的 SignData Compatblity 似乎有问题 请访问http://www.dustinhorne.com/post/Asymmetric-Encryption-and-Signing-with-RSA-in-Silverlight.aspx

我用它在客户端解密,即公共解密和 PHPSecLib 用于私有加密。

【讨论】:

    【解决方案3】:

    他们永远不会匹配。运行 C# 代码,它甚至不会与自身匹配。与 PHP 代码相同。 “问题”是 OAEP 和 PKCS#1 填充方法对它们具有随机分量,因此两个密文永远不会相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 2020-07-20
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多