非對稱技術棧實現AES加密解密javascript
正如前面的一篇文章所述,https協議的SSL層是實如今傳輸層之上,應用層之下,也就是說在應用層上看到的請求仍是明碼的,對於某些場景下要求這些http請求參數是非可讀的,這就要求在前端和後端不一樣的技術棧上完成信息的加密解密。固然咱們一般完成這樣專業的功能都會考慮使用相應的框架或者程序庫來完成功能,前端或者NodeJS平臺一般是JavaScript語言,JavaScript主流的加密解密庫分別是SjclJS和CryptoJS, 本文以CryptoJS爲例進行討論。另外在此處多提一句,JavaScript ES6標準已經完成了,如今的JavaScript已經不是當年的JavaScript了,Java該有的JavaScript也全有了,JavaScript做爲平臺,做爲一種嚴謹大項目開發的語言的日子已經不遠了,前幾天看到thoughtwork已經把ES6列爲了Adopt, 雖然瀏覽器尚未徹底支持,如今使用Babel已經能夠寫ES6代碼了,對了,ES6之後JavaScript已經支持class, 拉姆達表達式等等nb特性了,如今的JavaScript就是當年的Java,未來估計也是一個平臺。前端
書歸正傳,如示例所示,JavaScript中須要如今瀏覽器中引入相應的加密庫,而後就能夠調用相應的加密代碼,另外這個加密庫也支持NodeJS平臺,也能夠用以下方式引入和調用。須要說明的是NodeJS平臺下的npm安裝包和咱們下載的版本是不一樣的,這兩種版本不能混用。java
<script type="text/javascript" src="path-to/bower_components/crypto-js/crypto-js.js"></script> <script type="text/javascript"> var encrypted = CryptoJS.AES(...); var encrypted = CryptoJS.SHA256(...); </script>
var CryptoJS = require("crypto-js"); // Encrypt var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123'); // Decrypt var bytes = CryptoJS.AES.decrypt(ciphertext.toString(), 'secret key 123'); var plaintext = bytes.toString(CryptoJS.enc.Utf8); console.log(plaintext);
完整代碼示例以下所示算法
<script src="crypto-js.js"></script> <script> var data = "Hi There"; var key= iv= CryptoJS.enc.Latin1.parse('AjQ0YQ0MvKKC1uTr');//encrypt var encrypted = CryptoJS.AES.encrypt(data,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.ZeroPadding}); //decrypt var decrypted = CryptoJS.AES.decrypt(encrypted,key,{iv:iv,padding:CryptoJS.pad.ZeroPadding}); </script>
數據傳輸到服務端一樣須要加密解密纔可使用,不然獲得的就只有亂碼,沒有業務含義,下面分別以兩種主流服務端語言C#和Java來講明,服務端的代碼實現。須要說明的是單單實現一種平臺上的AES加密算法是簡單的只要找到相應的函數庫完成調用就能夠,可是若是須要完成跨平臺,跨技術棧,好比在JavaScript加密,C#解密,或者C#加密,Java解密就有些難度,本文的實現是能夠達到跨技術棧的目的。npm
C#後端
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; namespace UEncrypt { class UEncrypt { static void Main(string[] args) { String encryptData = Program.Encrypt("Hi There", "AjQ0YQ0MvKKC1uTr", "AjQ0YQ0MvKKC1uTr"); Console.WriteLine(encryptData); String decryptData = Program.Decrypt(encryptData, "AjQ0YQ0MvKKC1uTr", "AjQ0YQ0MvKKC1uTr"); Console.WriteLine(decryptData); Console.Read(); } public static string Encrypt(string toEncrypt, string key, string iv) { byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key); byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv); byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.IV = ivArray; rDel.Mode = CipherMode.CBC; rDel.Padding = PaddingMode.Zeros; ICryptoTransform cTransform = rDel.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } public static string Decrypt(string toDecrypt, string key, string iv) { byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key); byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv); byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.IV = ivArray; rDel.Mode = CipherMode.CBC; rDel.Padding = PaddingMode.Zeros; ICryptoTransform cTransform = rDel.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } } }
Java瀏覽器
public class UEncrypt { public static void main(String args[]) throws Exception { String data = encrypt() System.out.println(data); System.out.println(desEncrypt(data)); } public static String encrypt() throws Exception { try { String data = "Hi There"; String key = "AjQ0YQ0MvKKC1uTr"; String iv = "AjQ0YQ0MvKKC1uTr"; Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); int blockSize = cipher.getBlockSize(); byte[] dataBytes = data.getBytes(); int plaintextLength = dataBytes.length; if (plaintextLength % blockSize != 0) { plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize)); } byte[] plaintext = new byte[plaintextLength]; System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length); SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); byte[] encrypted = cipher.doFinal(plaintext); return new sun.misc.BASE64Encoder().encode(encrypted); } catch (Exception e) { } } public static String desEncrypt( String data ) throws Exception { try { String key = "AjQ0YQ0MvKKC1uTr"; String iv = key; byte[] encrypted1 = new BASE64Decoder().decodeBuffer(data); Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original); return originalString; } catch (Exception e) { } } }
總結框架
本文總結了JavaScript, C#, Java三種平臺上的AES加密解密算法實現,完整的實現了跨技術棧的加密解密,能夠在NodeJS加密,C#解密,但願對你們有所幫助。函數