RSA前台js加密,后台C#解密

一、需求:

     为了安全,项目中前台登陆用的密码需要加密传到后台,后台c#解密登陆密码。

二、解决方案

      采用非对称加密算法RSA来达到目的,前台登陆页面一加载便发送一次ajax请求获取后台产生的公钥,用于前台加密,用户点击登陆时出发加密过程并提交加密的数据到后台,后台C#语言采用已封装好的RSA算法工具进行密码解密。

     以下为c#RSA算法加密代码:

        private static RSAParameters rsap = new RSAParameters() {
            Modulus = Convert.FromBase64String(@"sB6+4rtO2sYeIZ8kJGGM647PIm+dJkwvSPNWcQ01D2cwPjIGV2c41h39FjYuzgAKzrIFjSvuBpG4y/PFEHuN+
                                                 LackSt6MU7qcbs7lzub8V97XZ5fddPaq/GWXo9mrIMMFDMW7z88WrukLGTvwkqySPBemc22rjua1uTR3azae7U="),
            Exponent = Convert.FromBase64String(@"AQAB"),
            P = Convert.FromBase64String(@"8yUCFVCufr3z2LDAwHaUO4r3na3WZqhAb3J7aXv/rj9UEXQWwZoG8IbUzV2fUhMXjnFXyrRSqywWdpxeE6oLWw=="),
            Q = Convert.FromBase64String(@"uW6NlpzkBl4Do7K4RUDCsZ9uiVqnU0cbm7JVuygWJts+pu1ho5s0auUekQy5al6p4xifjWIcCsLvPxsLuWISLw=="),
            DP = Convert.FromBase64String(@"rDsf0ad4I3E8hNcXgn28nLzgj8Hu6ILwOcGXZ+4c+/oB++cGo5cOqVxo6xwRWhsKCa2B6aV4FaZCNzymazl9lw=="),
            DQ = Convert.FromBase64String(@"dVVT+FKMIs9IZEPJP+DrkTM94WHgcNyUxp9Aii2iXrHqYfvhBYJG18Dk54lypbECtLU2+GJ1NgYFFxxI/ePldw=="),
            InverseQ = Convert.FromBase64String(@"z8qRY0+yyfZFNFPMtlTumpYyCXUbK+GpWnFp2hOyTABya/h7g4DCRE6iO9UZKgW4paB5K75mJwdBgVib5NgFiQ=="),
            D = Convert.FromBase64String(@"W1ZWoLeLWaJNlho2YDfHIZLakX1Y/reb/jVUqySyU96sAlVnPITn0QOUcaR/+Y3EDRX+EwypUPbZ48v0c2vgYDHwIb
                                           rIbsEyN+vHoUNJ319R5kUZ8Wlfw/w6/6BSclqbWQ8OdSj1cKwx/EEJh4iipqJ8HBTsmoT0anQHP/jdybE=")
        };

        private static string RSAEncrypt(string publicKey, string content) {

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);// RSACryptoServiceProvider();

            rsa.ImportParameters(rsap);//导入公钥

            byte[] result = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);

            return Convert.ToBase64String(result);
        }

        private static string RSADecrypt(string privateKey, string content) {

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);

            rsa.ImportParameters(rsap);

            var result = rsa.Decrypt(Convert.FromBase64String(content), false);

            return Encoding.UTF8.GetString(result);
        }

  后台传到前台的公钥信息为:

  rsap.Exponent.HexEncode();

  rsap.Modulus.HexEncode();

  HexEncode()为字节数组类型静态扩展,只为每个字节转化为对应的16进制,代码如下:

public static string ToHexEncode(this byte[] bytes) {
            return BitConverter.ToString(bytes).Replace("-", string.Empty);
        }

 采用上面静态对象rsap,经HexEncode传到前台的公钥信息为:

1.010001
2.B01EBEE2BB4EDAC61E219F2424618CEB8ECF226F9D264C2F48F356710D350F67303E3206576738D61DFD16362ECE000ACEB2058D2BEE0691B8CBF3C5107B
8DF8B69C912B7A314EEA71BB3B973B9BF15F7B5D9E5F75D3DAABF1965E8F66AC830C143316EF3F3C5ABBA42C64EFC24AB248F05E99CDB6AE3B9AD6E4D1DD
ACDA7BB5

前台js加密,从网上搜刮了RSA的js实现,页面需依次加入三个js文件:BigInt.js,Barrett.js,RSA.js,后面附上这三个js库。比如加密zjt,js代码如下:

setMaxDigits(130);
var key = new RSAKeyPair('010001', "", 'B01EBEE2BB4EDAC61E219F2424618CEB8ECF226F9D264C2F48F356710D350F67303E3206576738D61DFD163
62ECE000ACEB2058D2BEE0691B8CBF3C5107B8DF8B69C912B7A314EEA71BB3B973B9BF15F7B5D9E5F75D3DAABF1965E8F66AC830C143316EF3F3C5ABBA42C64
EFC24AB248F05E99CDB6AE3B9AD6E4D1DDACDA7BB5'); var res = encryptedString(key,'zjt')

 得到res为加密结果,用于会传到后台,res结果为:

9839c4f8cf40e5cd30be61a1e215c571424fca76108aacecc5ca45f9cdb6c207f4477eff32d41799babe915fd8806fce18ad38c4732d96008c506484940da7
a9b47cb7bc40f8bb70e079f8ae91e2b46d8d5d9bd1fa6ed637176d67a2a437ac801cca25f7e7c33b482d36f980da52982d65e6e388f2b2c47c7fcdfa797802
f2a5

  后台接收次加密的串,先转成字节,这里又用到了一个静态扩展HexDecode,转成字节,采用RSACryptoServiceProvider对象导入私钥进行解码:

 public static byte[] HexDecode(this string me)
 {
     string s = me.Length % 2 == 1 ? "0" + me : me;
     byte[] data = new byte[s.Length / 2];
     for (int i = 0; i < data.Length; i++)
         {
            data[i] = byte.Parse(s.Substring(i + i, 2), NumberStyles.HexNumber);
         }
         return data;
  }
public static string GetString(this byte[] content, Encoding encoding = null)
{
     encoding = encoding ?? Encoding.ASCII;
     return encoding.GetString(content);
}

解密过程如下:

var pass = "9839c4f8cf40e5cd30be61a1e215c571424fca76108aacecc5ca45f9cdb6c207f4477eff32d41799babe915fd8806fce18ad38c4732d96008c50648494
0da7a9b47cb7bc40f8bb70e079f8ae91e2b46d8d5d9bd1fa6ed637176d67a2a437ac801cca25f7e7c33b482d36f980da52982d65e6e388f2b2c47c7fcdfa797802
f2a5"; byte[] data = pass.HexDecode(); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024); rsa.ImportParameters(rsap); var res = rsa.Decrypt(data, false); Console.WriteLine(res.GetString());//用到上面静态扩展,解密后结果为zjt

RSA算法js实现

posted @ 2015-03-21 17:49  这是个坑  阅读(2365)  评论(1编辑  收藏  举报