標籤:
一、需求:
為了安全,項目中前台登陸用的密碼需要加密傳到後台,後台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.0100012.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實現
RSA前台js加密,後台C#解密