• RSA使用


    RSA使用

    今天在跟同事一起调试TCP通讯的时候,在RSA私钥解密这块,着实让我费了一番心思。
    流程大致是这样的,终端登录的时候使用固定的des密码加密数据发送,平台接收后确认登录信息后,会返回一个字符串,
    该字符串是使用rsa公钥加密的一个字符串,作为后续通讯时使用的des密码。平台是使用JAVA开发的,该私钥和公钥文件会
    在终端存一份。但是该文件是pem格式的,而且公钥使用证书的方式,调试使用公钥加密后的发送给平台,平台都是可以解密的。
    但是平台发送回来的公钥加密就是解密不正常。其中查找资料就不多说了,总算是解决了。这里做一个记录,也做个分享。
    其中使用到一个第三方库:BouncyCastle,可以使用NuGet来安装.
    首先是RSA密钥与Pem密钥的互转。

    /// <summary>
            /// Pem密钥转RSA密钥
            /// </summary>
            /// <param name="pemKey">Pem密钥</param>
            /// <param name="isPrivateKey">是否是私钥</param>
            /// <returns>RSA密钥</returns>
            public static string PemToRSAKey(string pemKeyFileName, bool isPrivateKey)
            {
                string rsaKey = string.Empty;
                object pemObject = null;
                RSAParameters rsaPara = new RSAParameters();
                using (StreamReader sReader = new StreamReader(pemKeyFileName))
                {
                    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sReader);
                    pemObject = pemReader.ReadObject();
    
                }
                //RSA私钥
                if (isPrivateKey)
                {
                    RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)pemObject;
                    rsaPara = new RSAParameters
                    {
                        Modulus = key.Modulus.ToByteArrayUnsigned(),
                        Exponent = key.PublicExponent.ToByteArrayUnsigned(),
                        D = key.Exponent.ToByteArrayUnsigned(),
                        P = key.P.ToByteArrayUnsigned(),
                        Q = key.Q.ToByteArrayUnsigned(),
                        DP = key.DP.ToByteArrayUnsigned(),
                        DQ = key.DQ.ToByteArrayUnsigned(),
                        InverseQ = key.QInv.ToByteArrayUnsigned(),
                    };
                }
                //RSA公钥
                else
                {
                    RsaKeyParameters key = (RsaKeyParameters)pemObject;
                    rsaPara = new RSAParameters
                    {
                        Modulus = key.Modulus.ToByteArrayUnsigned(),
                        Exponent = key.Exponent.ToByteArrayUnsigned(),
                    };
                }
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.ImportParameters(rsaPara);
                using (StringWriter sw = new StringWriter())
                {
                    sw.Write(rsa.ToXmlString(isPrivateKey ? true : false));
                    rsaKey = sw.ToString();
                }
                return rsaKey;
            }
            /// <summary>
            /// RSA密钥转Pem密钥
            /// </summary>
            /// <param name="RSAKey">RSA密钥</param>
            /// <param name="isPrivateKey">是否是私钥</param>
            /// <returns>Pem密钥</returns>
            public static string RSAKeyToPem(string RSAKey, bool isPrivateKey)
            {
                string pemKey = string.Empty;
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(RSAKey);
                RSAParameters rsaPara = new RSAParameters();
                RsaKeyParameters key = null;
                //RSA私钥
                if (isPrivateKey)
                {
                    rsaPara = rsa.ExportParameters(true);
                    key = new RsaPrivateCrtKeyParameters(
                        new BigInteger(1, rsaPara.Modulus), new BigInteger(1, rsaPara.Exponent), new BigInteger(1, rsaPara.D),
                        new BigInteger(1, rsaPara.P), new BigInteger(1, rsaPara.Q), new BigInteger(1, rsaPara.DP), new BigInteger(1, rsaPara.DQ),
                        new BigInteger(1, rsaPara.InverseQ));
                }
                //RSA公钥
                else
                {
                    rsaPara = rsa.ExportParameters(false);
                    key = new RsaKeyParameters(false,
                        new BigInteger(1, rsaPara.Modulus),
                        new BigInteger(1, rsaPara.Exponent));
                }
                using (TextWriter sw = new StringWriter())
                {
                    var pemWriter = new PemWriter(sw);
                    pemWriter.WriteObject(key);
                    pemWriter.Writer.Flush();
                    pemKey = sw.ToString();
                }
                return pemKey;
            }
    

    公钥加密,以证书方式打开pem密钥文件

     /// <summary>
    /// RSA公钥加密
    /// </summary>
    /// <param name="data"></param>
    /// <param name="publicKey"></param>
    /// <returns></returns>
    public static byte[] RSAPublicEncrypt(byte[] data, string publicKeyFileName)
    {
        X509Certificate2 x509Certificate2 = new X509Certificate2(publicKeyFileName);
        RSACryptoServiceProvider pubKey = (RSACryptoServiceProvider)x509Certificate2.PublicKey.Key;
        byte[] bys = pubKey.Encrypt(data, false);
        //string result = Convert.ToBase64String(bys);
        //return Encoding.UTF8.GetBytes(result);
        return bys;
    }
    

    私钥解密

     /// <summary>
    /// RSA私钥解密
    /// </summary>
    /// <param name="data"></param>
    /// <param name="privateKey"></param>
    /// <returns></returns>
    public static byte[] RSAPrivateDecrypt(byte[] data, string privateKeyFileName)
    {
        string xml = PemToRSAKey(privateKeyFileName, true);//将pem密钥转为RSA密钥
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(xml);
        return rsa.Decrypt(data, false);
    }
    
  • 相关阅读:
    Win32串口API
    Windows核心编程 第4章 进程
    大家都来吐槽下12306的网站bug吧
    HttpRequest模拟Post和Get提交代码
    jquery.masonry + jquery.infinitescroll 实现瀑布流布局
    三层架构之泛型应用
    listView 中,大图标时,各个图标之间间距的控制
    Windows Phone APP的设计过程
    分享三个小故事
    最值得创业者聆听的10大TED演讲(中文字幕视频)
  • 原文地址:https://www.cnblogs.com/zzr-stdio/p/11240329.html
Copyright © 2020-2023  润新知