RSA Подписание с помощью PHP и проверка с помощью C # - PullRequest
0 голосов
/ 09 марта 2012

Я создаю приложение, которое является клиентским (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);

Ответы [ 3 ]

0 голосов
/ 13 марта 2012

Кажется, что-то не так с SignData Compatablity из PhpSecLib & C # RSA. Пожалуйста, посетите http://www.dustinhorne.com/post/Asymmetric-Encryption-and-Signing-with-RSA-in-Silverlight.aspx

Я использовал это для дешипрования на клиенте, т.е. Public Decrypt и PHPSecLib для частного шифрования.

0 голосов
/ 15 марта 2012

Они никогда не совпадут. Запустите код C #, и он не будет совпадать даже с самим собой. То же самое с кодом PHP. «Проблема» в том, что методы заполнения OAEP и PKCS # 1 содержат случайный компонент, поэтому два зашифрованных текста никогда не будут одинаковыми.

0 голосов
/ 09 марта 2012

Возможно, этот метод расширения будет полезен:

    /// <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).

...