http://www.cnblogs.com/revealit/p/6094750.html基于C#的RSA非对称加密算法

最近在搞单点登录的设计,在设计中需要一个Token令牌的加密传输,这个令牌在整个连接单点的各个站中起着连接认证作用,如果被仿造将会有不可预计的损失,但是这个Token是要可逆的。所以像那种md5,sha之类的不可逆加密就没法用了,然后可逆的加密主要是分为对称加密和非对称加密。

  • 对称加密:用加密的钥匙来解密,比如DES,AES的加解密。
  • 非对称加密:一个钥匙加密,用另一个钥匙解密。

直接看下面的方法:

1、首先生成密钥对

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 /// <summary> /// RSA加密的密匙结构  公钥和私匙 /// </summary> public struct RSAKey {      public string PublicKey { get ; set ; }      public string PrivateKey { get ; set ; } }   #region 得到RSA密匙对 /// <summary> /// 得到RSA密匙对 /// </summary> /// <returns></returns> public static RSAKey GetRASKey() {      RSACryptoServiceProvider.UseMachineKeyStore = true ;      RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(DWKEYSIZE);      RSAParameters p = rsaProvider.ExportParameters( true );        return new RSAKey()      {          PublicKey = ComponentKey(p.Exponent, p.Modulus),          PrivateKey = ComponentKey(p.D, p.Modulus)      }; } #endregion #region 将密匙组合成base64字符串 /// <summary> /// 将密钥组合成base64编码字符串 /// </summary> private static string ComponentKey( byte [] b1, byte [] b2) {      List< byte > list = new List< byte >();      list.Add(( byte )b1.Length);      list.AddRange(b1);      list.AddRange(b2);      byte [] b = list.ToArray< byte >();      return Convert.ToBase64String(b); }   /// <summary> /// 从base64字符串,解析原来的密钥 /// </summary> private static void ResolveKey( string key, out byte [] b1, out byte [] b2) {      //从base64字符串 解析成原来的字节数组      byte [] b = Convert.FromBase64String(key);      //初始化参数的数组长度      b1 = new byte [b[0]];      b2 = new byte [b.Length - b[0] - 1];      //将相应位置是值放进相应的数组      for ( int n = 1, i = 0, j = 0; n < b.Length; n++)      {          if (n <= b[0])          {              b1[i++] = b[n];          }          else          {              b2[j++] = b[n];          }      } } #endregion

简要的说明一下上面这段代码,做了3件事:生成RSA密码,把公钥和私钥分别转为密钥字符串,把密钥字符串转为对应的公私钥。

为什么多了一个公私钥和字符串之间的相互转换,太蛋疼的动作,好吧,我懂你。

2、公有的明文加解密算法

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #region 字符串加密解密 公开方法 /// <summary> /// 字符串加密 /// </summary> /// <param name="source">源字符串 明文</param> /// <param name="key">密匙</param> /// <returns>加密遇到错误将会返回原字符串</returns> public static string EncryptString( string source, string key) {      string encryptString = string .Empty;      byte [] d;      byte [] n;      try      {          if (!CheckSourceValidate(source))          {              throw new Exception( "source string too long" );          }          //解析这个密钥          ResolveKey(key, out d, out n);          BigInteger biN = new BigInteger(n);          BigInteger biD = new BigInteger(d);          encryptString = EncryptString(source, biD, biN);      }      catch      {          encryptString = source;      }      return encryptString; }   /// <summary> /// 字符串解密 /// </summary> /// <param name="encryptString">密文</param> /// <param name="key">密钥</param> /// <returns>遇到解密失败将会返回原字符串</returns> public static string DecryptString( string encryptString, string key) {      string source = string .Empty;      byte [] e;      byte [] n;      try      {          //解析这个密钥          ResolveKey(key, out e, out n);          BigInteger biE = new BigInteger(e);          BigInteger biN = new BigInteger(n);          source = DecryptString(encryptString, biE, biN);      }      catch      {          source = encryptString;      }      return source; } #endregion

3、私有的加解密算法

《http://www.cnblogs.com/revealit/p/6094750.html基于C#的RSA非对称加密算法》

#region 字符串加密解密 私有  实现加解密的实现方法
/// <summary>
/// 用指定的密匙加密 
/// </summary>
/// <param name="source">明文</param>
/// <param name="d">可以是RSACryptoServiceProvider生成的D</param>
/// <param name="n">可以是RSACryptoServiceProvider生成的Modulus</param>
/// <returns>返回密文</returns>
private static string EncryptString(string source, BigInteger d, BigInteger n)
{
    int len = source.Length;
    int len1 = 0;
    int blockLen = 0;
    if ((len % 128) == 0)
        len1 = len / 128;
    else
        len1 = len / 128 + 1;
    string block = "";
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < len1; i++)
    {
        if (len >= 128)
            blockLen = 128;
        else
            blockLen = len;
        block = source.Substring(i * 128, blockLen);
        byte[] oText = System.Text.Encoding.Default.GetBytes(block);
        BigInteger biText = new BigInteger(oText);
        BigInteger biEnText = biText.modPow(d, n);
        string temp = biEnText.ToHexString();
        result.Append(temp).Append("@");
        len -= blockLen;
    }
    return result.ToString().TrimEnd('@');
}

/// <summary>
/// 用指定的密匙加密 
/// </summary>
/// <param name="source">密文</param>
/// <param name="e">可以是RSACryptoServiceProvider生成的Exponent</param>
/// <param name="n">可以是RSACryptoServiceProvider生成的Modulus</param>
/// <returns>返回明文</returns>
private static string DecryptString(string encryptString, BigInteger e, BigInteger n)
{
    StringBuilder result = new StringBuilder();
    string[] strarr1 = encryptString.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
    for (int i = 0; i < strarr1.Length; i++)
    {
        string block = strarr1[i];
        BigInteger biText = new BigInteger(block, 16);
        BigInteger biEnText = biText.modPow(e, n);
        string temp = System.Text.Encoding.Default.GetString(biEnText.getBytes());
        result.Append(temp);
    }
    return result.ToString();
}
#endregion

《http://www.cnblogs.com/revealit/p/6094750.html基于C#的RSA非对称加密算法》

4、使用方式

?

1 2 3 4 5 6 7 8 string str = "{\"sc\":\"his51\",\"no\":\"1\",\"na\":\"管理员\"}{\"sc\":\"@his51\",\"no\":\"1\",\"na\":\"管理员\"}{\"sc\":\"his51\",\"no\":\"1\",\"na\":\"管员\"}{\"sc\":\"his522" ; RSAHelper.RSAKey keyPair = RSAHelper.GetRASKey(); Console.WriteLine( "公钥:" + keyPair.PublicKey + "\r\n" ); Console.WriteLine( "私钥:" + keyPair.PrivateKey + "\r\n" ); string en = RSAHelper.EncryptString(str, keyPair.PrivateKey); Console.WriteLine( "加密后:" +en + "\r\n" ); Console.WriteLine( "解密:" +RSAHelper.DecryptString(en, keyPair.PublicKey) + "\r\n" ); Console.ReadKey();

附件:RSAtest.rar

 

附:

都说RSA解密效率太低,这里附加一个表:

序号

原文件大小(KB

加密后文件大小(KB

加密用时(

解密用时(

1      

6

6

0

1

2      

12

12

0

3

3      

24

24

0

5

4      

45

45

0

10

5      

90

90

1

21

6      

180

180

2

40

7      

360

360

2

98

8      

720

721

2

165

9      

1440

1440

5

325

由于Token才几百个字节,效率上没测试过解密效果,但安全和这若干毫秒哪个更重要?答案不言而明。

    原文作者:加密算法
    原文地址: https://www.cnblogs.com/Chareree/p/8708667.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞