新公司对于用户密码保护十分严密,采用了两种加密方式,
例如修改密码时,仅加密流程如下
首先在前端使用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() + "}");
}