vue 核心加解密工具類 方法


  1  /* base64 加解密
  2   */
  3  export let Base64 = require('js-base64').Base64
  4 
  5  /* md5 加解密
  6  */
  7  export let crypto = require('crypto');
  8  export let md5 = require('js-md5');
  9  export let CryptoJS = require('crypto-js');
 10  export let MD5 = CryptoJS.MD5;
 11  /*
 12   *引入jsencrypt實現數據RSA加密
 13   */
 14  import JSEncrypt from 'jsencrypt';
 15  // jsencrypt.js處理長文本數據時報錯  Message too long for RSA
 16  // encryptlong是基於jsencrypt擴展的長文本分段加解密功能。
 17  import Encrypt from "encryptlong";
 18  // rsa sign
 19  import jsrsasign from 'jsrsasign'
 20 
 21  // Message Digest algorithm 5,信息摘要算法
 22  // alglorithm:md5、sha1、sha256
 23  export function Md5(plainText, alglorithm, encoding){
 24    const hash =  crypto.createHash(alglorithm)
 25    hash.update(plainText);//加密內容
 26    return  hash.digest(encoding);//密文
 27  }
 28 
 29  //Hash Message Authentication Code,散列消息鑒別碼
 30  //Secure Hash Algorithm,安全散列算法
 31  // alglorithm:md5、sha256、sha1
 32  export function HMac(plainText, secretKey,alglorithm, encoding){
 33    const hmac= crypto.createHmac(alglorithm, secretKey);
 34    const cipherText= hmac.update(plainText);//加密內容
 35    return  cipherText.digest(encoding);//密文
 36  }
 37 
 38  //Data Encryption Standard,數據加密算法
 39  // DES/DES3/AES 加密, key與iv長度必須是8的倍數
 40  //mode:CryptoJS.mode.CBC、CryptoJS.mode.ECB、CryptoJS.mode.CFB
 41  //padding:CryptoJS.pad.ZeroPadding、CryptoJS.pad.Pkcs7、CryptoJS.pad.NoPadding
 42  export function encrypt ( algorithm, plainText,key, iv, mode, padding, isBase64) {
 43      key = key ? key : "abcdefghijklmnop";
 44      iv = iv ? iv : "0102030405060708";
 45 
 46      const keyHex = CryptoJS.enc.Utf8.parse(key);
 47      const ivHex = CryptoJS.enc.Utf8.parse(iv);
 48      const option = { iv:keyHex,mode: mode, padding: padding }
 49      let encrypted = null  ;
 50      if(algorithm === "TripleDES"){
 51        encrypted = CryptoJS.TripleDES.encrypt(plainText, keyHex, option)
 52      }else if(algorithm === "DES"){
 53        encrypted = CryptoJS.DES.encrypt(plainText, keyHex, option)
 54      }
 55      else if(algorithm === "AES"){
 56        encrypted =  CryptoJS.AES.encrypt(plainText, keyHex, option)
 57      }
 58      return isBase64?CryptoJS.enc.Base64.stringify(encrypted.ciphertext):encrypted.ciphertext.toString();
 59  }
 60 
 61  // DES/DES3/AES解密,key與iv長度必須是8的倍數
 62  export function decrypt (algorithm,cipherText,key, iv, mode, padding, isBase64) {
 63      key = key ? key : "abcdefghijklmnop";
 64      iv = iv ? iv : "0102030405060708";
 65 
 66      const keyHex = CryptoJS.enc.Utf8.parse(key);
 67      const ivHex = CryptoJS.enc.Utf8.parse(iv);
 68      const decryptText = isBase64?  CryptoJS.enc.Base64.parse(cipherText):cipherText;
 69      const textHex = { ciphertext:  isBase64?decryptText:CryptoJS.enc.Hex.parse(decryptText) }
 70      const option = { iv:ivHex,mode: mode, padding: padding }
 71      let decrypted = null;
 72      if(algorithm === "TripleDES"){
 73        decrypted = CryptoJS.TripleDES.decrypt(textHex, keyHex, option);
 74      }else if(algorithm === "DES"){
 75        decrypted = CryptoJS.DES.decrypt(textHex, keyHex, option);
 76      }
 77      else if(algorithm === "AES"){
 78        decrypted =  CryptoJS.AES.decrypt(textHex, keyHex, option);
 79      }
 80      return decrypted.toString(CryptoJS.enc.Utf8);
 81  }
 82 
 83  /** RSA 加密過程
 84   * (1)A生成一對密鑰(公鑰和私鑰),私鑰不公開,A自己保留。公鑰為公開的,任何人可以獲取。
 85   * (2)A傳遞自己的公鑰給B,B用A的公鑰對消息進行加密。
 86   * (3)A接收到B加密的消息,利用A自己的私鑰對消息進行解密。
 87   *  在這個過程中,只有2次傳遞過程,第一次是A傳遞公鑰給B,第二次是B傳遞加密消息給A,即使都被敵方截獲,也沒有危險性。
 88   *  因為只有A的私鑰才能對消息進行解密,防止了消息內容的泄露。
 89   *  使用方法
 90   *  客戶端初始化訪問服務器端時,服務器端會生成一對RSA對,及公鑰和密鑰。
 91   *  如果前端只需要將要傳給后端的數據進行加密后傳輸,那么前端可以只要公鑰,通過公鑰對要傳輸的參數進行加密后把加密的字符串發給后端,后端取出保存的密碼種子或者直接保存的私鑰,采用私鑰對加密字符串進行解密,得到明文。
 92   *  如果前端要獲取后端傳過來的已經加密后的字符串,並且解密使用,那么前端就需要拿到RSA對立面的私鑰進行解密后使用了。
 93   * */
 94  /* JSEncrypt 公鑰加密  padding:pkcs1pad2 */
 95  export function RsaJSEncrypt(plainText,publicKey) {
 96    const jsencrypt = new JSEncrypt({
 97      default_key_size: 1024
 98    });
 99    jsencrypt.setPublicKey(publicKey);
100    // 如果是對象/數組的話,需要先JSON.stringify轉換成字符串
101    // 處理中文亂碼,服務器端:String result = java.net.URLDecoder.decode(cipherText ,"UTF-8");
102    const cipherText = encodeURIComponent(jsencrypt.encrypt(plainText));
103    return  cipherText;
104  }
105 
106  /* JSEncrypt 私鑰解密 padding:pkcs1pad2 */
107  export function RsaJSDecrypt(cipherText,privateKey) {
108    const jsencrypt = new JSEncrypt({
109      default_key_size: 1024
110    });
111    jsencrypt.setPrivateKey(privateKey);
112    return jsencrypt.decrypt(decodeURIComponent(cipherText));
113  }
114 
115  /* 長文本分段加密 */
116  export function RsaEncrypt(plainText,publicKey) {
117    const encryptor = new Encrypt();
118    encryptor.setPublicKey(publicKey);
119    // 處理中文亂碼,服務器端:String result = java.net.URLDecoder.decode(cipherText ,"UTF-8");
120    const cipherText = encodeURIComponent(encryptor.encryptLong(plainText));
121    return  cipherText;
122  }
123 
124  /* 長文本分段解密 */
125  export function RsaDecrypt(cipherText,privateKey) {
126    var encryptor = new Encrypt();
127    encryptor.setPrivateKey(privateKey);
128    return encryptor.decryptLong(decodeURIComponent(cipherText));
129  }
130 
131  // 獲取簽名 privateKey_s 服務器端的私鑰
132  export function RsaSign(plainText,privateKey_s,format_key, alglorithm,isBase64)
133  {
134    // 生成簽名對象
135    let sign = genSign(privateKey_s,format_key, alglorithm);
136 
137     plainText = genDigest(plainText,alglorithm);
138     sign.updateString(plainText);
139 
140     // +號服務器端不識別,url編碼
141     return isBase64? encodeURIComponent(jsrsasign.hextob64(sign.sign())):encodeURIComponent(sign.sign());
142  }
143 
144  // 驗證簽名 publicKey_s 服務器端的公鑰
145  // alglorithm: SHA1withRSA、MD5withRSA、SHA256withRSA、 SHA384withRSA、SHA512withRSA、RIPEMD160withRSA
146  // format_key: PKCS#1、PKCS#5、PKCS#8
147  /*
148   * PKCS#1:定義RSA公開密鑰算法加密和簽名機制,主要用於組織PKCS#7中所描述的數字簽名和數字信封。
149   * PKCS#3:定義Diffie-Hellman密鑰交換協議。
150   * PKCS#5:描述一種利用從口令派生出來的安全密鑰加密字符串的方法。使用MD2或MD5 從口令中派生密鑰,並采用DES-CBC模式加密。主要用於加密從一個計算機傳送到另一個計算機的私人密鑰,不能用於加密消息[24]。
151   * PKCS#6:描述了公鑰證書的標准語法,主要描述X.509證書的擴展格式。
152   * PKCS#7:定義一種通用的消息語法,包括數字簽名和加密等用於增強的加密機制,PKCS#7與PEM兼容,所以不需其他密碼操作,就可以將加密的消息轉換成PEM消息[26]。
153   * PKCS#8:描述私有密鑰信息格式,該信息包括公開密鑰算法的私有密鑰以及可選的屬性集等。
154   * PKCS#9:定義一些用於PKCS#6證書擴展、PKCS#7數字簽名和PKCS#8私鑰加密信息的屬性類型。
155   * PKCS#10:描述證書請求語法。
156   * PKCS#11:稱為Cyptoki,定義了一套獨立於技術的程序設計接口,用於智能卡和PCMCIA卡之類的加密設備。
157   * PKCS#12:描述個人信息交換語法標准。描述了將用戶公鑰、私鑰、證書和其他相關信息打包的語法。
158   * PKCS#13:橢圓曲線密碼體制標准。
159   * PKCS#14:偽隨機數生成標准。
160   * PKCS#15:密碼令牌信息格式標准。
161   */
162  export function RsaVerifySign(plainText,signedText,publicKey_s,format_key, alglorithm,isBase64)
163  {
164    // 生成簽名
165    let verifySign = genSign(publicKey_s,format_key, alglorithm);
166    // 根據明文生成摘要
167    let digestText = genDigest(plainText,alglorithm);
168 
169    verifySign.updateString(digestText);
170 
171    return  verifySign.verify(isBase64?jsrsasign.b64tohex(decodeURIComponent(signedText)):decodeURIComponent(signedText));
172  }
173 
174  // 根據明文生成摘要
175  //SHA1withRSA、MD5withRSA、SHA256withRSA、 SHA384withRSA、SHA512withRSA、RIPEMD160withRSA
176  export function genDigest(plainText,alglorithm, ){
177    let option = { "alg": alglorithm.split('w')[0], "prov":"cryptojs/jsrsa", }
178    let text = new jsrsasign.KJUR.crypto.MessageDigest(option);   // 摘要
179    text.updateString(plainText);
180    return text.digest();
181  }
182 
183  /* 生成rsa簽名對象
184   * */
185  export function genSign(RsaKey_s,format_key, alglorithm)
186  {
187    //私鑰要寫開頭和結束
188    // var private_key = '-----BEGIN PRIVATE KEY-----' + privateKey_s + '-----END PRIVATE KEY-----'
189    // 讀取解析pem格式的秘鑰, 生成秘鑰實例 (RSAKey)
190    let rsaKey = new jsrsasign.RSAKey();
191    if (format_key === "PKCS#1" || format_key === "PKCS#5"|| format_key === "PKCS#7"|| format_key === "PKCS#8") {
192      rsaKey = jsrsasign.KEYUTIL.getKey(RsaKey_s);
193      // rsaSign.readPrivateKeyFromPEMString(privateKey_s);
194    }
195 
196    let option= {
197      "alg":alglorithm,
198      "prov":"cryptojs/jsrsa",
199      "prvkeypem": rsaKey
200    };
201 
202    let sign = new jsrsasign.KJUR.crypto.Signature(option);
203    sign.init(rsaKey);
204 
205    return sign;
206  }

測試代碼:

 1  // 測試工具:http://www.1818288.com/   http://www.metools.info/
 2       console.log("12345678漢字abcdef,md5="+this.$md5("12345678漢字abcdef"));
 3       console.log("12345678,MD5="+this.$MD5("12345678"));
 4       console.log("12345678,Md5="+this.$Md5("12345678","md5","hex"));
 5       console.log("12345678,HMac-MD5="+this.$HMac("12345678漢字abcdef","abcdef","md5","hex"));
 6       console.log("12345678,enDES="+this.$Encrypt("DES","12345678","abcdef","abcdef",this.$CryptoJS.mode.CBC,this.$CryptoJS.pad.ZeroPadding,true));
 7       console.log("12345678,deDES="+this.$Decrypt("DES","CQlZsExZRQM=","abcdef","abcdef",this.$CryptoJS.mode.CBC,this.$CryptoJS.pad.ZeroPadding,true));
 8 
 9       console.log("12345678,enDES3="+this.$Encrypt("TripleDES","12345678","abcdef","abcdef",this.$CryptoJS.mode.ECB,this.$CryptoJS.pad.Pkcs7,true));
10       console.log("12345678,deDES3="+this.$Decrypt("TripleDES","Wb6LDNctz2HpGd1QX22oNQ==","abcdef","abcdef",this.$CryptoJS.mode.ECB,this.$CryptoJS.pad.Pkcs7,true));
11 
12       console.log("12345678,enAES="+this.$Encrypt("AES","12345678","","",this.$CryptoJS.mode.ECB,this.$CryptoJS.pad.Pkcs7,false));
13       console.log("12345678,deAES="+this.$Decrypt("AES","5a9906baab69bdcd17a0f925cbb3dbb3","","",this.$CryptoJS.mode.ECB,this.$CryptoJS.pad.Pkcs7,false));
14 
15       console.log("12345678,enAES="+this.$Encrypt("AES","12345678","","",this.$CryptoJS.mode.ECB,this.$CryptoJS.pad.Pkcs7,true));
16       console.log("12345678漢字abcdef,deAES="+this.$Decrypt("AES","WpkGuqtpvc0XoPkly7Pbsw==","","",this.$CryptoJS.mode.ECB,this.$CryptoJS.pad.Pkcs7,true));
17 
18       let plainText = "12345678漢字abcdef";
19 
20       let publicKey = "MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFrtUneGIrf/hc7l9JUR+OCCDWqq\n" +
21         "ttX2pItsbg0fpZ6Zl0rCoZwuaRc5ltoVhIPvT2HEUYJrUmNwamtfXqZaxkvOtxpc\n" +
22         "GWB8nR3r9XTSE3/iuI7jMvXqP5HiWWoiT8IKwxaa3P5pu5UF5q/2t+/8XGeiGAoc\n" +
23         "WLiZ/HPpeZyQVUfXAgMBAAE=";
24 
25       let privateKey = "MIICWgIBAAKBgFrtUneGIrf/hc7l9JUR+OCCDWqqttX2pItsbg0fpZ6Zl0rCoZwu\n" +
26         "aRc5ltoVhIPvT2HEUYJrUmNwamtfXqZaxkvOtxpcGWB8nR3r9XTSE3/iuI7jMvXq\n" +
27         "P5HiWWoiT8IKwxaa3P5pu5UF5q/2t+/8XGeiGAocWLiZ/HPpeZyQVUfXAgMBAAEC\n" +
28         "gYAbawi9BfOeLCz7MJhKAzta55yIF6Y+ars/V5jv2CUm6AWZA4ub/tqtqC324Rou\n" +
29         "dpEnV/2EKDyVw6YzbnSqESFOCVNYOslqSLhSStkuvBYo3Tr1/8ITt1JKxcqS6Lix\n" +
30         "VVp4zl+MgBvYNOv1pbubsc76lMB1TirFN6U0iFsPKuBrgQJBALTqGJjbgI/Idvsi\n" +
31         "Z5ycE3kyD+ZLOYCDY3/GKh8xcD93iXRIj5AY4vA6Tqnb56eDY4GvXGEQaJpNAJ9z\n" +
32         "Ukq4G6ECQQCAqjEfELqDA2dLdV9fojYxq1j/PGlBUWlt0+8cEsOBTbMfD9Kt5diM\n" +
33         "b1Ut213I2z07ZFNHDouBOK8x4iDYanB3AkASchPT8f1nq47GCDn8M8Wgg8QvPNg+\n" +
34         "DCdm7bN5vratIej33DYXARKSX7+Jfgxeffz1SgXnN58SrGs11rI7QA5BAkB0BwZd\n" +
35         "GVzYoM0ZwzLKryFoETkkknnoqV4F6MUL7+/WPxd0v3Qh1dA+dHe/7r7YTr0dPg/L\n" +
36         "WFZ9pXx344/zGalpAkB8QBNZej44DU+nAi6KQVEbLxOps1BbyzzWfXI2uQRR+w52\n" +
37         "ABLacpwutsHC8jLjUDaCLfFUaEnpkBWW8u0pI54v";
38 
39       let cipherText =this.$RsaEncrypt(plainText,publicKey,false,true);
40       console.log("12345678漢字abcdef,RSAEn_pubK="+cipherText);
41 
42       console.log("12345678漢字abcdef,RSADe_priK="+this.$RsaDecrypt(cipherText, privateKey,false,true));
43 
44       cipherText = this.$RsaJSEncrypt(plainText, publicKey,false,true);
45 
46       console.log("12345678漢字abcdef,RSAJSEn_pubK="+cipherText);
47 
48       console.log("12345678漢字abcdef,RSAJSDe_priK="+this.$RsaJSDecrypt(cipherText, privateKey,false,true));
49 
50 
51       let signPrivateKey = "-----BEGIN PRIVATE KEY-----\n" +
52         "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOihfrud6pbH6y9m\n" +
53         "MGpG870wcZyKqwmedUmQH1cwsyOiJZZib0J4IlxRq6yTAuLRnXHM1JBnvvJl6oBH\n" +
54         "tvM6vSj6kSDY0SCuoARdp1oJH7BXLTcEVXIbGxD+/6ZcapydzcnBMtkHpG+pgf9c\n" +
55         "lf57z/aqewEAq00Z+rH+yWuyggITAgMBAAECgYEAnacEeiWVG8Y0jpTUbtHS0P4J\n" +
56         "oKshKo2mssnnU3F/lcCHdJkVCZjcwG/gxj2DETA5YSwNSifk8eU7vN/dDo1aLyZn\n" +
57         "+qc9rot+jHW+z8hXHWm+RbC8CkD7KMjd2RlRBcnSXieoUqqKyrwYL2JPecG22CFp\n" +
58         "QcvbAPT0ITor0lKNt4ECQQD7OGHxzM4DfG+tXj3RvWgk7I6lcHL4s7ad3hdkjkVe\n" +
59         "x+fHKybiCzl4o9dXS9iObw4xg54k7sKYs+S+6AsNKlazAkEA7Q6Rscpocw+dYQMv\n" +
60         "SdLIwB3eqUkcVxbvj9C/hFm5LqzvAMhcGQBp4Hp9OHILuqEYqFxuyIbCOyhbBJMo\n" +
61         "bBJXIQJBAM74F7FnYv76QOObNeEbY7av8aGZMA93t+b991XP5JT+qxSql4E5cCLV\n" +
62         "EO+JvCM0mYPvhJW24zl9U+J4N8qj7AMCQA9VROk6DV174hMXUKS2xJNgmzlZ6EJd\n" +
63         "0mr79pdJ8mdpeiAT1ZksZKzHX3gaMFYG+4BQUj4YMVIAPzrhhdjPquECQQDBFWVi\n" +
64         "ByzngHyXCuVpDN3FKZ26Cnqt8mY2kW8N+4/okQ+rPzxt86TywPerIGR1qAl5PgDS\n" +
65         "gMZzSWvMDuT8369m\n" +
66         "-----END PRIVATE KEY-----";
67 
68       let signPublicKey = "-----BEGIN PUBLIC KEY-----\n" +
69         "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDooX67neqWx+svZjBqRvO9MHGc\n" +
70         "iqsJnnVJkB9XMLMjoiWWYm9CeCJcUauskwLi0Z1xzNSQZ77yZeqAR7bzOr0o+pEg\n" +
71         "2NEgrqAEXadaCR+wVy03BFVyGxsQ/v+mXGqcnc3JwTLZB6RvqYH/XJX+e8/2qnsB\n" +
72         "AKtNGfqx/slrsoICEwIDAQAB\n" +
73         "-----END PUBLIC KEY-----";
74 
75       let signedText = this.$RsaSign(plainText,signPrivateKey,"PKCS#8","MD5withRSA",true,true);
76 
77       console.log("12345678漢字abcdef,RSASign_priK="+signedText);
78 
79 
80       console.log("12345678漢字abcdef,RSAVerifySign_pubK="+this.$RsaVerifySign(plainText,signedText,
81         signPublicKey,"PKCS#8","MD5withRSA",true,true));
82 
83       signedText = this.$RsaSign("12345678漢字abcdef",signPrivateKey,"PKCS#1","SHA1withRSA",true,true);
84         console.log("12345678漢字abcdef,RSASign_priK="+signedText);
85 
86 
87       console.log("12345678漢字abcdef,RSAVerifySign_pubK="+this.$RsaVerifySign(plainText, signedText,
88         signPublicKey,"PKCS#1","SHA1withRSA",true,true));

 

測試結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM