• 分享RSA的一点东西


    摘要:至于RSA是什么,基本概念去园子里面搜索,讲的详细的大神大有人在。今天在此记录,对接第三方支付中的MD5WithRSA签名问题。
    我这边是用C#开发接口需要使用rsa私钥进行签名,对方使用的Java,出现签名问题在所难免。
    签名与加密解释:用A的私钥签名,B用A给的公钥验证签名,可以保证该信息是由A发送的。B用A的公钥加密,A用私钥解密,可以保证该信息只能由A接收到。
    废话少说现给出代码
    1、私钥签名字符串

    //私钥是java生成的一串字符串,并不是pfx文件
    /// <summary>      
    /// RSA私钥格式转换,java->.net      
    /// </summary>      
    /// <param name="privateKey">java生成的RSA私钥</param>      
    /// <returns></returns>     
    public static string RSAPrivateKeyJava2DotNet(string privateKey)
    {
        RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
        return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
        Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
        Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
        Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
        Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
        Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
        Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
        Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
        Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
    }
    
    /// <summary>
    /// PrivateKey为java生成的一串字符串rsa密钥
    /// </summary>
    /// <param name="signdata">需要签名的字符串</param>
    /// <returns></returns>
    public static string DataSign(string signdata)
    {
        string xmlPrivateKey = RSAPrivateKeyJava2DotNet(PrivateKey);
        //加载私钥  
        RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();
        privateRsa.FromXmlString(xmlPrivateKey);
    
        byte[] buffer = Encoding.UTF8.GetBytes(signdata);
        var MSG_SIGN = Convert.ToBase64String(privateRsa.SignData(buffer, "md5"));
        return MSG_SIGN;
    }
    

    2、私钥加密字符串
    RSA私钥长度为1024则可加密的字符串为127(1024/8-11),依次类推。所以当需要加密的字符串过大的时候,必须要进行分段加密,直接给出代码

    /// <summary>
    /// 用私钥给数据进行RSA加密   
    /// </summary>  
    /// <param name="xmlPrivateKey">私钥</param>  
    /// <param name="m_strEncryptString">待加密数据</param>  
    /// <returns>加密后的数据(Base64)</returns>  
    public static string RSAEncryptByPrivateKey(string PrivateKey, string strEncryptString)
    {
        string xmlPrivateKey = RSAPrivateKeyJava2DotNet(PrivateKey);
    
        //加载私钥  
        RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();
        privateRsa.FromXmlString(xmlPrivateKey);
    
        //转换密钥  
        AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);
        
        // 参数与Java中加密解密的参数一致
        IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
        
        //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
        c.Init(true, keyPair.Private);
    
        byte[] DataToEncrypt = Encoding.UTF8.GetBytes(strEncryptString);
    
    
        //对超过数据进行分段加密
        byte[] bytes = Encoding.UTF8.GetBytes(strEncryptString);
        int inputlen = bytes.Length;
        byte[] cache;
        MemoryStream ms = new MemoryStream();
        int offset = 0;
        int i = 0;
        while (inputlen - offset > 0)
        {
            if (inputlen - offset > 117)
            {
                cache = c.DoFinal(DataToEncrypt, offset, 117);
            }
            else
            {
                cache = c.DoFinal(DataToEncrypt, offset, inputlen - offset);
            }
            ms.Write(cache, 0, cache.Length);
            i++;
            offset = i * 117;
        }
        byte[] resultbytes = ms.ToArray();
    
        //byte[] outBytes = c.DoFinal(DataToEncrypt);//加密  
        string strBase64 = Convert.ToBase64String(resultbytes);
    
        return strBase64;
    }
    
  • 相关阅读:
    2017年3月笔记
    2017年2月笔记
    2017年1月笔记
    2016年12月笔记
    2016年11月笔记
    2016年10月笔
    2016年9月笔记
    2016年8月笔记
    2016年7月笔记
    2016年6月笔记
  • 原文地址:https://www.cnblogs.com/xuxuzhaozhao/p/6740046.html
Copyright © 2020-2023  润新知