.net的rsa签名与php、java如何才能互通?
我要提的是.net的rsa签名与php、java不一致的问题,也参考了网上不少的资料,但总是得不到和php签名后一样的结果。
示例证书地址:http://kx.w918.com/cer.zip 其中.pfx为私钥,私钥的密码是123456
要签名的内容是
merchantName=翰鑫科技&merchantId=303310048990001&merchantOrderId=123234244&merchantOrderTime=20111012135602&merchantOrderAmt=1&merchantOrderDesc=自动订购&transTimeout=20111012135802我用C#签名得到的结果
eyJxHrfDnLU2mhvH3AmTj72IjdIjxnHTVzDBt69AfN7ErBDIhMTVS+oT4UTlQEsvJS3/PvohFzYhnSpTpxnnZuQ89kdi1qhbRkwWysOOP+HTjxtOWshvmTp+XGfXoyyk4wZlsnYIm4ckuq59F52wxUWroQBZCGCasWPdM/iydHs=而PHP签名得到的结果是
Gx2KtW8fB7ctK6n3f4Q3VgB+7pZRyY2alpJpIIQTanlvh1dnUXBa6KBNyuq/X1s5NmfWaIesA/WasL28H1qUoSgrvJK9rVzjvU6O5ayjvUlXrZ7aS6oZhrgHSK4lEqshtvv5RVzJwkQQxbqXR4JVfaPUSmWhzfvfb6dkpsccBNc=
     
         /*
         *  这是PHP签名代码
         *  public static function sign($data, $privateKeyPath, $privateKeyPassword)
            {
                $dateMd5 = md5($data, true);
                $p12cert = array();
                $fd = fopen($privateKeyPath, 'r');
                $p12buf = fread($fd, filesize($privateKeyPath));
                fclose($fd);
                if (openssl_pkcs12_read($p12buf, $p12cert, $privateKeyPassword)) {            
                    //var_dump($p12cert);            
                    $private_key = $p12cert['pkey'];
                    //私钥加密
                    openssl_private_encrypt($dateMd5, $crypted, $private_key);            
                    //var_dump(base64_encode($dateMd5));            
                    return base64_encode($crypted);
                } else {
                    return "";
                }
            }
         *  php 从pfx文件中取出的私钥
         *  MIICWwIBAAKBgQCgAJ0Q5ayYsIt+KW953jroMLg3K7mnaZL1vOHyWNa0t1NQzOvSaADPr9VMHDCF0gb7RoVDY2R7MBT9z2F7QeSOtX1dszou1GdPRUt/CVWk7euSbv7sRqrvqGJXokbkf3oZ/PZgocaPFlDIt/TTr5MT3YyylgjHBKX36UekRUzqswIDAQABAoGAdngd094LDr9heZeah8SpHzS7oXYJr9B21Ob28WcgCozW7rPcRF1nhF+v8fvJXbxmGPVdRMk6JBA06rz7c7UVUf2OhqbQc8nBHJLruqAiaHnDTH875iLngzX+LiPFWMr57T3nUGeqCAlx5KwjXrifo2UBpi/KBXgyZmj3VWVHbtkCQQDLuXhADwtkVb70r4QI+PLDrEQwB+mzDo8ZJE92CKjAXjvLXFJz0yZSF+1a9YBh+lG4MN4DZ2yrxgJFReOlAElHAkEAyQ8RUfqdgm8BBJy7ZNNk+fM4GJZ9jXdyeREX6QjFvqly64MYHnArQAfuGMyPCgOUSsHm+iXKftFf3muEMiPJNQJAaVrNGTOujIDbc+agvZMg2Jhp2vz8mqDY2AOzJDNuMa2J9q0T5to3YxUEppl3fzPYtwxuhAwkYuDPo8t04ou3WQJAfCdOxbWhD8sl8Mgru24CO4piCGTdcL7itDnG7wKYwUx3h1CzUxBm1KpQ74VZipB9QNCNpcgyS69UqM7xmdiZRQJAFvwVE/XPhOETS+Vt8mNaDlaSNW0LP0Aog5WevcVS1Jeeg+iDkpa9PXKUB+nP4SAC06tz9yRRs+6OSQAlUrq8lw==
         *
         *  php 签名的的原文
         *  merchantName=翰鑫科技&merchantId=303310048990001&merchantOrderId=123234244&merchantOrderTime=20111012135602&merchantOrderAmt=1&merchantOrderDesc=自动订购&transTimeout=20111012135802
         *
         *  php 将原文MD5后的Base64
         *  vFI598yiPhn7qhXpJI97aw==
         *
         *  php 签名后的Base64
         *  Gx2KtW8fB7ctK6n3f4Q3VgB+7pZRyY2alpJpIIQTanlvh1dnUXBa6KBNyuq/X1s5NmfWaIesA/WasL28H1qUoSgrvJK9rVzjvU6O5ayjvUlXrZ7aS6oZhrgHSK4lEqshtvv5RVzJwkQQxbqXR4JVfaPUSmWhzfvfb6dkpsccBNc=
        */        //这是C#签名的代码
        //strForSign 的值为 php 签名的的原文
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        byte[] rgbHash = md5.ComputeHash(Encoding.UTF8.GetBytes(strForSign));
        //创建证书文件 MY_private_key 为PFX文件的路径 MY_prikey_password为证书的密码123456
        X509Certificate2 objx5092 = new X509Certificate2(MY_private_key, MY_prikey_password);
        //取出私钥
        RSACryptoServiceProvider rsa = objx5092.PrivateKey as RSACryptoServiceProvider;
        RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(rsa);
        formatter.SetHashAlgorithm("MD5");//摘要算法MD5
        //签名
        byte[] SignData = formatter.CreateSignature(rgbHash);
        //将签名之后的数据进行base64编码 
        string signature = Convert.ToBase64String(SignData);
        

解决方案 »

  1.   

    pkcs会对原文进行混淆填充,一般来说经过pkcs得到的密文每次都不一样,直接对比密文是没意义的,直接用C#去解php的密文如果能解出来就没问题。
      

  2.   

    ".net的rsa签名与php、java如何才能互通 ? ",是什么意思啊,是.net的rsa与php、java能否结合着使用的意思吗?
      

  3.   


    不是的,php、java的RSA签名是标准的,
    而.net的是在标准的基础上又增加了一个随机数在其中,导致出来的结果不能在java中验证
    而且java的byte的范围是-128~127,而.net的范围是0-255
    总之一句话:.net的rsa签名如何能在java中验证通过