小程序AES加密、解密

小程序AES加密、解密,第1张

npm install  crypto-js

import CryptoJS from 'crypto-js'

// 定义加/解密的 key

const initKey = 'Test-AES-CBC-128'

// 设置数据块长度

const keySize = 128

//设置向量和服务端保持一致

const iv = "0abcdefghij7twhjm"

export const aesEncrypt = (data, key) =>{

  /**

  * CipherOption, 加密的一些选项:

  * mode: 加密模式, 可取值(CBC, CFB, CTR, CTRGladman, OFB, ECB), 都在 CryptoJS.mode 对象下

  * padding: 填充方式, 可取值(Pkcs7, AnsiX923, Iso10126, Iso97971, ZeroPadding, NoPadding), 都在 CryptoJS.pad 对象下

  * iv: 偏移量, mode === ECB 时, 不需要 iv

  * 返回的是一个加密对象

  */

  const cipher = CryptoJS.AES.encrypt(data, key, {

    mode: CryptoJS.mode.CBC,

    padding: CryptoJS.pad.Pkcs7,

    iv: CryptoJS.enc.Utf8.parse(iv)

  })

// 将加密后的数据转换成 Base64

  const base64Cipher = cipher.ciphertext.toString(CryptoJS.enc.Base64)//CryptoJS.enc.Base64

  console.log('base64Cipher', base64Cipher)

// 处理 Android 某些低版的BUG

//    const resultCipher = base64Cipher.replace('//+/g,\'-\'').replace(g,'_')

// 返回加密后的经过处理的 Base64

  return base64Cipher

}

/**

* 解密函数

* @param {string} encrypted - 加密的数据

* @param {string} key - 加密使用的 key

*/

export const aesDecrypt = (encrypted, key) =>{

// 先将 Base64 还原一下, 因为加密的时候做了一些字符的替换

//      const restoreBase64 = encrypted.replace().replace(/_/g,'/')

// 这里 mode, padding, iv 一定要跟加密的时候完全一样

// 返回的是一个解密后的对象

  const decipher = CryptoJS.AES.decrypt(encrypted, key, {

    mode: CryptoJS.mode.CBC,

    padding: CryptoJS.pad.Pkcs7,

    iv: CryptoJS.enc.Utf8.parse(iv)

  })

// 将解密对象转换成 UTF8 的字符串

  const resultDecipher = CryptoJS.enc.Utf8.stringify(decipher)

// 返回解密结果

  return resultDecipher

}

首先准备一份明文和秘钥:

var plaintText = 'aaaaaaaaaaaaaaaa'// 明文

var keyStr = 'bbbbbbbbbbbbbbbb'// 一般key为一个字符串

参看官网文档,AES方法是支持AES-128、AES-192和AES-256的,加密过程中使用哪种加密方式取决于传入key的类型,否则就会按照AES-256的方式加密。

CryptoJS supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a passphrase, then it will generate a 256-bit key.

由于Java就是按照128bit给的,但是由于是一个字符串,需要先在前端将其转为128bit的才行。

最开始以为使用CryptoJS.enc.Hex.parse就可以正确地将其转为128bit的key。但是不然...

经过多次尝试,需要使用CryptoJS.enc.Utf8.parse方法才可以将key转为128bit的。好吧,既然说了是多次尝试,那么就不知道原因了,后期再对其进行更深入的研究。

// 字符串类型的key用之前需要用uft8先parse一下才能用

var key = CryptoJS.enc.Utf8.parse(keyStr)

由于后端使用的是PKCS5Padding,但是在使用CryptoJS的时候发现根本没有这个偏移,查询后发现PKCS5Padding和PKCS7Padding是一样的东东,使用时默认就是按照PKCS7Padding进行偏移的。

// 加密

var encryptedData = CryptoJS.AES.encrypt(plaintText, key, {

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7

})

由于CryptoJS生成的密文是一个对象,如果直接将其转为字符串是一个Base64编码过的,在encryptedData.ciphertext上的属性转为字符串才是后端需要的格式。

var encryptedBase64Str = encryptedData.toString()

// 输出:'RJcecVhTqCHHnlibzTypzuDvG8kjWC+ot8JuxWVdLgY=

console.log(encryptedBase64Str)

// 需要读取encryptedData上的ciphertext.toString()才能拿到跟Java一样的密文

var encryptedStr = encryptedData.ciphertext.toString()

// 输出:'44971e715853a821c79e589bcd3ca9cee0ef1bc923582fa8b7c26ec5655d2e06

console.log(encryptedStr)

由于加密后的密文为128位的字符串,那么解密时,需要将其转为Base64编码的格式。

那么就需要先使用方法CryptoJS.enc.Hex.parse转为十六进制,再使用CryptoJS.enc.Base64.stringify将其变为Base64编码的字符串,此时才可以传入CryptoJS.AES.decrypt方法中对其进行解密。

// 拿到字符串类型的密文需要先将其用Hex方法parse一下

var encryptedHexStr = CryptoJS.enc.Hex.parse(encryptedStr)

// 将密文转为Base64的字符串

// 只有Base64类型的字符串密文才能对其进行解密

var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr)

使用转为Base64编码后的字符串即可传入CryptoJS.AES.decrypt方法中进行解密 *** 作。

// 解密

var decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, {

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7

})

经过CryptoJS解密后,依然是一个对象,将其变成明文就需要按照Utf8格式转为字符串。

// 解密后,需要按照Utf8的方式将明文转位字符串

var decryptedStr = decryptedData.toString(CryptoJS.enc.Utf8)

console.log(decryptedStr)// 'aaaaaaaaaaaaaaaa'

1.程序加密可结合AES算法,在程序运行中,通过外部芯片中的AES密钥,加密数据来验证双方的正确性,称之为对比认证。

2.加密数据传输过程中,可通过AES加密后形成密文传输,到达安全端后再进行解密,实现数据传输安全控制。

3.综合1和2,当前高大上的方式是程序加密可进行移植到加密芯片,存储在加密芯片中,运行也在加密芯片内部运行,输入数据参数,返回执行结果,同时辅助以AES加密和认证,实现数据程序的全方位防护


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11820526.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存