RSA加密(前端js)和MD5加密(后台)同时使用实例
新公司对于用户密码保护十分严密,采用了两种加密方式,
例如修改密码时,仅加密流程如下
首先在前端使用RSA加密方式对密码进行一次加密,数据传到后台, 然后RSA解密,最后存入数据库前,再进行一次MD5盐值加密
功能实现如下
项目中引用一个js文件 文件名 jsencrypt.min.js
下载地址:https://pan.baidu.com/s/1Nmb183-5-x8NmVu83ftnYg 提取码: w3a7
前台加密部分:
var encrypt = new JSEncrypt(); encrypt.setPublicKey("此处为RSA公钥"); var myPassword="123456"; myPassword= encodeURI(myPassword).replace(/\+/g, '%2B');
此时即得到加密处理过的密码
后台处理部分:
注意添加命名空间 using System.Security.Cryptography;
private string Encryption(string myPassword, string key) { //RSA解密 string privateKey = "此处为RSA私钥"; RSACreatKey RsaCreate = new RSACreatKey(); RSACryptoServiceProvider rsaCryptoServiceProvider = RsaCreate.CreateRsaKeyPair(privateKey); byte[] rc = rsaCryptoServiceProvider.Decrypt(Convert.FromBase64String(myPassword.Replace("%2B", "+")), false); //MD5+盐值加密后返回 return MD5password.MD5Encoding(Encoding.UTF8.GetString(rc), key); }
RSA具体解密过程 即 RSACreatKey 类中CreateRsaKeyPair方法
public RSACryptoServiceProvider CreateRsaKeyPair(string privateKey) { var privateKeyBits = System.Convert.FromBase64String(privateKey); var RSA = new RSACryptoServiceProvider(); var RSAparams = new RSAParameters(); using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits))) { byte bt = 0; ushort twobytes = 0; twobytes = binr.ReadUInt16(); if (twobytes == 0x8130) binr.ReadByte(); else if (twobytes == 0x8230) binr.ReadInt16(); else throw new Exception("Unexpected value read binr.ReadUInt16()"); twobytes = binr.ReadUInt16(); if (twobytes != 0x0102) throw new Exception("Unexpected version"); bt = binr.ReadByte(); if (bt != 0x00) throw new Exception("Unexpected value read binr.ReadByte()"); RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.D = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.P = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr)); RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr)); } RSA.ImportParameters(RSAparams); return RSA; } private int GetIntegerSize(BinaryReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) return 0; bt = binr.ReadByte(); if (bt == 0x81) count = binr.ReadByte(); else if (bt == 0x82) { highbyte = binr.ReadByte(); lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; } while (binr.ReadByte() == 0x00) { count -= 1; } binr.BaseStream.Seek(-1, SeekOrigin.Current); return count; }
MD5盐值加密过程 //即MD5password类中的MD5Encoding方法
//MD5加密 public static string MD5Encoding(string psw)
{ MD5 md5 = MD5.Create(); byte[] bs = Encoding.UTF8.GetBytes(psw); byte[] hs = md5.ComputeHash(bs); StringBuilder stb = new StringBuilder(); foreach (byte b in hs) { // 以十六进制格式格式化 stb.Append(b.ToString("x2")); } return stb.ToString(); } //MD5盐值加密 public static string MD5Encoding(string rawPass, object salt) { if (salt == null) return rawPass; return MD5Encoding(rawPass + "{" + salt.ToString() + "}"); }