简体   繁体   English

使用PHP进行RSA签名并使用C#进行验证

[英]RSA Signing with PHP and verifying with C#

I'm building an application which is Client (C#) & Server (PHP) based application. 我正在构建一个基于客户端(C#)和服务器(PHP)的应用程序。

I want to sign the data on Server using RSA-SHA1 and send to client. 我想使用RSA-SHA1在服务器上签名数据并发送给客户端。

On Server ie PHP I' using PHPSecLib , signing with Private Key. 在服务器上,即PHP,我使用PHPSecLib ,并使用私钥签名。 On client ie C# I'm using RSACryptoServiceProvider. 在客户端即C#上,我正在使用RSACryptoServiceProvider。 Sign Hash from Server is not matching with the client. 来自服务器的Sign Hash与客户端不匹配。 I'm providing both C# and PHP Codes: 我同时提供C#和PHP代码:

PHP #Output PHP#输出

BLkgXU6t6IYNdlrgTaJgaGzZtSc9NjY9q67PbidGo0e79SyQ7b18uKSg1a215r583atzIlFYkAyxDCjvQJIBATdeOKpWuzdtRkZqDX7TQAw5jLHdsFjL3lQWABERFUdEs9XuCykb3I8UNVT2UgmMRZ3pyKknCMdc5AlE9mKXOYI=

PHP Code 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# Output C#输出

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

C# Code 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);

Perhaps this extension method will be of help: 也许这种扩展方法会有所帮助:

    /// <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;
    }

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

The passPharse parameter in this case is optional. 这种情况下的passPharse参数是可选的。 This is if you want to append some kind of salt to it. 这是如果您要在其中添加某种盐。 Also, be sure to watch out for spaces and linebreaks (CRLF). 另外,请务必当心空格和换行符(CRLF)。

It seems there is something wrong with SignData Compatablity of PhpSecLib & C# RSA Please do visit http://www.dustinhorne.com/post/Asymmetric-Encryption-and-Signing-with-RSA-in-Silverlight.aspx PhpSecLib和C#RSA的SignData兼容性似乎有问题,请访问http://www.dustinhorne.com/post/Asymmetric-Encryption-and-Signing-with-RSA-in-Silverlight.aspx

I used this to decypt at client ie Public Decrypt and PHPSecLib for private Encyption. 我用它在客户端(例如,Public Decrypt和PHPSecLib)上进行私有加密。

They'll never match. 他们永远不会匹配。 Run the C# code and it won't match even with itself. 运行C#代码,即使它本身也不匹配。 Same with the PHP code. 与PHP代码相同。 The "problem" is that OAEP and PKCS#1 padding methods have a random component to them so two ciphertext's will never be the same. “问题”在于OAEP和PKCS#1填充方法对它们具有随机成分,因此两个密文永远不会相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM