【絕跡篇】C#RSA算法實現


當下最流行的RSA加密算法,只有公鑰和私鑰同時擁有才能破解加密信息,RSA加密算法的出現有利於數據安全性傳輸

1.C#中自帶RSACryptoServiceProvider類可以讓你很好的生成XML格式的公鑰和私鑰,兩句代碼就搞定

2.但是生成的XML格式前端不能很好的利用和讀懂,所以在生成的XML格式里需要轉換成PEM格式,這樣才能直接Copy到驗證工具里加密解密,非常方便
首先,我們先導入一個第三方庫,因為下面涉及到的轉換代碼都是需要依賴這個庫來實現,導入操作如下

控制台里輸入
PM > Install-Package BouncyCastle
導入到引用里面

3.好了,下面就是純代碼實現了,目的就是將XML格式轉換為PEM格式,無論公鑰還是私鑰,不羅嗦直接代碼走起

        static void Main(string[] args)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            string xmlPrivateKey = rsa.ToXmlString(true);//XML密鑰
            string pemPrivateKey = Xml2PemPrivate(xmlPrivateKey, "F:/privatePEM.txt");//PEM密鑰

            string xmlPublicKey = rsa.ToXmlString(false);//XML公鑰
            string pemPublicKey = Xml2PemPublic(xmlPublicKey, "F:/publicPEM.txt");//PEM公鑰
        }

        /// <summary>
        ///  XML格式公鑰轉PEM格式公鑰
        /// </summary>
        /// <param name="xml">XML格式的公鑰</param>
        /// <param name="saveFile">保存文件的物理路徑</param>
        public static string Xml2PemPublic(string xml, string saveFile)
        {
            var rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(xml);
            var p = rsa.ExportParameters(false);
            RsaKeyParameters key = new RsaKeyParameters(false, new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent));
            using (var sw = new StreamWriter(saveFile))
            {
                var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
                pemWriter.WriteObject(key);
            }

            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key);
            byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
            string publicKey = Convert.ToBase64String(serializedPublicBytes);
            return Format(publicKey, 1);
        }

        /// <summary>
        ///  XML格式私鑰轉PEM
        /// </summary>
        /// <param name="xml">XML格式私鑰</param>
        /// <param name="saveFile">保存文件的物理路徑</param>
        public static string Xml2PemPrivate(string xml, string saveFile)
        {
            var rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(xml);
            var p = rsa.ExportParameters(true);
            var key = new RsaPrivateCrtKeyParameters(
                new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
                new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ),
                new BigInteger(1, p.InverseQ));
            using (var sw = new StreamWriter(saveFile))
            {
                var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
                pemWriter.WriteObject(key);
            }

            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(key);
            byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
            string privateKey = Convert.ToBase64String(serializedPrivateBytes);
            return Format(privateKey, 2);
        }

        /// <summary>
        ///  格式化公鑰/私鑰
        /// </summary>
        /// <param name="key">生成的公鑰/私鑰</param>
        /// <param name="type">1:公鑰 2:私鑰</param>
        /// <returns>PEM格式的公鑰/私鑰</returns>
        public static string Format(string key, int type)
        {
            string result = string.Empty;

            int length = key.Length / 64;
            for (int i = 0; i < length; i++)
            {
                int start = i * 64;
                result = result + key.Substring(start, 64) + "\r\n";
            }

            result = result + key.Substring(length * 64);
            if (type == 1)
            {
                result = result.Insert(0, "-----BEGIN PUBLIC KEY-----\r\n");
                result += "\r\n-----END PUBLIC KEY-----";
            }
            if (type == 2)
            {
                result = result.Insert(0, "-----BEGIN PRIVATE KEY-----\r\n");
                result += "\r\n-----END PRIVATE KEY-----";
            }

            return result;
        }

4.最后輸出在F盤的TXT文件里面就是可以直接用來Copy到驗證工具里面直接加密/解密數據用的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM