閱讀922 返回首頁    go 阿裏雲 go 技術社區[雲棲]


RSA加密算法

RSA算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰。RSA算法是第一個能同時用於加密和數字簽名的算法,也易於理解和操作。

原理圖:


C# 代碼實現:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using Microsoft.Win32;
using System.IO;

namespace SRA
{
    class Program
    {
        static void Main(string[] args)
        {
            string publicKeyFile = "publicKey.txt";
            string privateKeyFile = "privateKey.txt";
            string publicKey = string.Empty;
            string privateKey = string.Empty;
            Console.WriteLine("①創建公私鑰對:");
            RSA.GenneralRSAKey(privateKeyFile, publicKeyFile);
            publicKey = RSA.ReadPublicKey(publicKeyFile);
            privateKey = RSA.ReadPrivateKey(privateKeyFile);
            Console.WriteLine("公鑰:" + publicKey);
            Console.WriteLine("私鑰:" + privateKey);
            string orgStr = "HelloWord";
            Console.WriteLine("②使用公鑰加密字符串:");
            string secStr = RSA.RSAEncrypt(publicKey, orgStr);
            Console.WriteLine(secStr);
            Console.WriteLine("③使用私鑰解密字符串:");
            Console.WriteLine(SRA.RSA.RSADecrypt(privateKey, secStr));

            Console.Read();
        }
    }
    public class RSA
    {
        #region  ①生成公私鑰對
        /// <summary>
        /// ①生成公私鑰對
        /// </summary>
        /// <param name="PrivateKeyPath">私鑰文件路徑</param>
        /// <param name="PublicKeyPath">公鑰文件路徑</param>
        public static void GenneralRSAKey(string PrivateKeyPath, string PublicKeyPath)
        {
            try
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                CreatePrivateKeyXML(PrivateKeyPath, provider.ToXmlString(true));
                CreatePublicKeyXML(PublicKeyPath, provider.ToXmlString(false));
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }
        #region 創建密鑰文件
        /// <summary>
        /// 創建公鑰文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="publickey"></param>
        public static void CreatePublicKeyXML(string path, string publickey)
        {
            try
            {
                if (File.Exists(path))
                {
                    File.Delete(path);
                }
                FileStream publickeyxml = new FileStream(path, FileMode.Create);
                StreamWriter sw = new StreamWriter(publickeyxml);
                sw.WriteLine(publickey);
                sw.Close();
                publickeyxml.Close();
            }
            catch
            {
                throw;
            }
        }
        /// <summary>
        /// 創建私鑰文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="privatekey"></param>
        public static void CreatePrivateKeyXML(string path, string privatekey)
        {
            try
            {
                if (File.Exists(path))
                {
                    File.Delete(path);
                }
                FileStream privatekeyxml = new FileStream(path, FileMode.Create);
                StreamWriter sw = new StreamWriter(privatekeyxml);
                sw.WriteLine(privatekey);
                sw.Close();
                privatekeyxml.Close();
            }
            catch
            {
                throw;
            }
        }
        #endregion
        #endregion
        #region ②讀取密鑰
        /// <summary>
        /// 讀取公鑰
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string ReadPublicKey(string path)
        {
            StreamReader reader = new StreamReader(path);
            string publickey = reader.ReadToEnd();
            reader.Close();
            return publickey;
        }
        /// <summary>
        /// 讀取私鑰
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string ReadPrivateKey(string path)
        {
            StreamReader reader = new StreamReader(path);
            string privatekey = reader.ReadToEnd();
            reader.Close();
            return privatekey;
        }
        #endregion
        #region ③加密解密
        /// <summary>
        /// RSA加密
        /// </summary>
        /// <param name="xmlPublicKey">公鑰</param>
        /// <param name="m_strEncryptString">MD5加密後的數據</param>
        /// <returns>RSA公鑰加密後的數據</returns>
        public static string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
        {
            string str2;
            try
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                provider.FromXmlString(xmlPublicKey);
                byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
                str2 = Convert.ToBase64String(provider.Encrypt(bytes, false));
            }
            catch (Exception exception)
            {
                throw exception;
            }
            return str2;
        }
        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="xmlPrivateKey">私鑰</param>
        /// <param name="m_strDecryptString">待解密的數據</param>
        /// <returns>解密後的結果</returns>
        public static string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
        {
            string str2;
            try
            {
                RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
                provider.FromXmlString(xmlPrivateKey);
                byte[] rgb = Convert.FromBase64String(m_strDecryptString);
                byte[] buffer2 = provider.Decrypt(rgb, false);
                str2 = new UnicodeEncoding().GetString(buffer2);
            }
            catch (Exception exception)
            {
                throw exception;
            }
            return str2;
        }
        #endregion  
    }
}


算法介紹:

        算法的名字以發明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman。早在1973年,英國國家通信總局的數學家Clifford Cocks就發現了類似的算法。但是他的發現被列為絕密,直到1998年才公諸於世。

  RSA算法是一種非對稱密碼算法,所謂非對稱,就是指該算法需要一對密鑰,使用其中一個加密,則需要用另一個才能解密。

  RSA的算法涉及三個參數,n、e1、e2。

  其中,n是兩個大質數p、q的積,n的二進製表示時所占用的位數,就是所謂的密鑰長度。

  e1和e2是一對相關的值,e1可以任意取,但要求e1與(p-1)*(q-1)互質;再選擇e2,要求(e2*e1)mod((p-1)*(q-1))=1。

  (n及e1),(n及e2)就是密鑰對。

  RSA加解密的算法完全相同,設A為明文,B為密文,則:A=B^e1 mod n;B=A^e2 mod n;

  e1和e2可以互換使用,即:A=B^e2 mod n;B=A^e1 mod n;




最後更新:2017-04-02 06:51:55

  上一篇:go IO學習筆記(二)
  下一篇:go Java Listener 模式