基于@ohos/crypto-js实现加解密工具箱

HarmonyOS官方账号
发布于 2024-10-9 09:18
浏览
0收藏

​@ohos/crypto-js简介

@ohos/crypto-js是一个根据crypto-js库移植的鸿蒙三方库,适配源库4.2.0版本,提供了一系列加密算法和安全工具,主要用于执行各种消息摘要计算和对称加解密操作。

@ohos/crypto-js与cryptoFramework规格对比

算法类别

算法名称

@ohos/crypto-js

cryptoFramework

消息摘要

MD5

支持

支持

SHA-1

支持

支持

SHA-2

支持

支持

SHA-3

支持

不支持

RIPEMD160

支持

不支持

SM3

不支持

支持

消息认证码

HMAC

支持

支持

密钥派生

PBKDF2

支持

支持

EVPKDF

支持

不支持

对称加解密

AES

支持

支持

DES

支持

不支持

TripleDES

支持

支持

RC4

支持

不支持

Rabbit

支持

不支持

Rabbit-legacy

支持

不支持

SM4

不支持

支持

非对称加解密

RSA

不支持

支持

SM2

不支持

支持


@ohos/crypto-js不支持国密算法和非对称加解密算法,国密算法可以使用三方库​​@yyz116/sm-crypto

​消息摘要算法

MD5算法

MD5(Message-Digest Algorithm 5)是一种广泛使用的散列函数,用于生成128位(32个十六进制数字)的消息摘要。

demo展示

基于@ohos/crypto-js实现加解密工具箱-鸿蒙开发者社区

代码实现

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

  • 一次性加密

调用CryptoJS.MD5接口,传入明文,生成密文。

// MD5加密 
let mdOutput = CryptoJS.MD5('Message').toString()
  • 分段加密

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

调用CryptoJS.algo.MD5.create接口创建Hasher对象,通过update方法传入多段明文,通过finalize方法生成密文。

// 创建MD5Hasher实例 
let md = CryptoJS.algo.MD5.create() 
// 分段传入明文 
md.update("Message Part 1") 
md.update("Message Part 2") 
md.update("Message Part 3") 
// 完成加密,输出密文 
let mdOutput = md.finalize().toString()

SHA算法

demo展示

基于@ohos/crypto-js实现加解密工具箱-鸿蒙开发者社区

SHA-1

SHA-1是基于MD4散列算法设计的,SHA-1接受最大长度为2^64位的消息,并生成一个160位的散列值。

代码实现

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

  • 一次性加密

调用CryptoJS.SHA1接口,传入明文,生成密文。

// SHA1加密 
let sha1Output = CryptoJS.SHA1('Message').toString()
  • 分段加密

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

调用CryptoJS.algo.SHA1.create接口创建Hasher对象,通过update方法传入多段明文,通过finalize方法生成密文。

// 创建SHA1Hasher实例 
let sha1 = CryptoJS.algo.SHA1.create() 
// 分段传入明文 
sha1.update("Message Part 1") 
sha1.update("Message Part 2") 
sha1.update("Message Part 3") 
// 完成加密,输出密文 
let sha1Output = sha1.finalize().toString()

SHA-2

SHA-2是一系列散列函数的统称,包括SHA-224、SHA-256、SHA-384和SHA-512等。

代码实现

  • 一次性加密(以SHA-256为例)

调用CryptoJS.SHA256接口,传入明文,生成密文。

// SHA2加密 
let sha256Output = CryptoJS.SHA256('Message').toString()
  • 分段加密(以SHA-256为例)

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

调用CryptoJS.algo.SHA256.create接口创建Hasher对象,通过update方法传入多段明文,通过finalize方法生成密文。

// 创建SHA2Hasher实例 
let sha256 = CryptoJS.algo.SHA256.create() 
// 分段传入明文 
sha256.update("Message Part 1") 
sha256.update("Message Part 2") 
sha256.update("Message Part 3") 
// 完成加密,输出密文 
let sha256Output = sha256.finalize().toString()

SHA-3

SHA-3是NIST在2015年正式发布的散列函数标准,采用了全新的结构。

代码实现

  • 一次性加密

调用CryptoJS.SHA3接口,传入明文与输出长度,生成密文。输出长度可以为224、256、384、512,默认为512。

// SHA3加密,可以配置输出长度 
let sha3Output = CryptoJS.SHA3('Message', { outputLength: 256 }).toString()
  • 分段加密

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

调用CryptoJS.algo.SHA3.create接口并配置输出长度创建Hasher对象,通过update方法传入多段明文,通过finalize方法生成密文。

// 创建SHA3Hasher实例 
let sha3Output = CryptoJS.algo.SHA3.create({ outputLength: 256 }) 
// 分段传入明文 
sha3Output.update("Message Part 1") 
sha3Output.update("Message Part 2") 
sha3Output.update("Message Part 3") 
// 完成加密,输出密文 
let sha3OutputOutput = sha3Output.finalize().toString()

消息认证码算法

HMAC算法

HMAC(Hash-based Message Authentication Code)是一种基于哈希函数和密钥的消息认证码算法。

demo展示

基于@ohos/crypto-js实现加解密工具箱-鸿蒙开发者社区

代码实现

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

  • 一次性加密(以SHA-256为例)

调用CryptoJS.HmacSHA256接口,传入明文与密钥,生成密文。

// HMAC加密,使用SHA256算法 
let hmacSHA256Output = CryptoJS.HmacSHA256("Message", "Secret Passphrase").toString()
  • 分段加密(以SHA-256为例)

调用 CryptoJS.algo.HMAC.create接口,配置HasherStatic对象和密钥创建HMAC对象,HasherStatic可以使用crypto-js支持的任意摘要算法,如CryptoJS.algo.SHA256。通过update方法传入多段明文,通过finalize方法生成密文。

// 创建HMAC算法实例,配置SHA256 HasherStatic对象和密钥 
let hmacSHA256 = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, "Secret Passphrase") 
// 分段传入明文 
hmacSHA256.update("Message Part 1") 
hmacSHA256.update("Message Part 2") 
hmacSHA256.update("Message Part 3") 
// 完成加密,输出密文 
let hmacSHA256Output = hmacSHA256.finalize().toString()

密钥派生算法

PBKDF2算法

PBKDF2(Password-Based Key Derivation Function 2)是一种基于密码的密钥生成算法。

demo展示

基于@ohos/crypto-js实现加解密工具箱-鸿蒙开发者社区

代码实现

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

  • 一次性加密(以SHA256为例)

调用CryptoJS.PBKDF2接口,参数为密码、盐值、密钥长度、消息摘要算法、迭代次数,生成新密码。

// PBKDF2加密,可以自定义密钥长度、哈希算法和迭代次数 
let pbkdf2SHA256Output = CryptoJS.PBKDF2("Message", "salt", { 
    keySize: 10,  // 密钥长度、 
    hasher: CryptoJS.algo.SHA256,  // 哈希算法 
    iterations: 100 // 迭代次数 
}).toString()
  • 分段加密(以SHA256为例)

调用CryptoJS.algo.PBKDF2.create接口,配置密钥长度、消息摘要算法、迭代次数创建PBKDF2对象。

通过compute方法传入分段密码和盐值生成密码WordArray对象,通过数组克隆与拼接操作生成完整新密码。

   // 创建PBKDF2算法实例,配置密钥长度、哈希算法和迭代次数 
let pbkdf2SHA256 = CryptoJS.algo.PBKDF2.create({ 
       keySize: 10, 
       hasher: CryptoJS.algo.SHA256, 
       iterations: 100 
   }) 
   // 分段传入密码和盐值,分段生成新密码 
   let pbkdf2SHA256Output1 = pbkdf2SHA256.compute("Message Part 1", "salt") 
   let pbkdf2SHA256Output2 = pbkdf2SHA256.compute("Message Part 2", "salt") 
   let pbkdf2SHA256Output3 = pbkdf2SHA256.compute("Message Part 3", "salt") 
   // 拼接成完整新密码 
   let pbkdf2SHA256Output = pbkdf2SHA256Output1.clone() 
   .concat(pbkdf2SHA256Output2) 
   .concat(pbkdf2SHA256Output3) 
   .toString()

对称加解密算法

DES算法

DES(Data Encryption Standard)加密是一种对称加密算法。

demo展示

基于@ohos/crypto-js实现加解密工具箱-鸿蒙开发者社区

代码实现

根据数据量,可以分段也可以不分段,该算法库目前没有对单次加密的数据量设置大小限制。

建议对于大数据量的对称加解密,采用多次分段的方式传入数据。

  • 一次性加密

DES加密可以配置的加密参数为明文、密钥、模式、填充、偏移量。

明文、密钥、偏移量通常会在加解密前解析成对应编码的WordArray对象。

crypto-js支持的加密模式:CBC、ECB、CFB、CTR、OFB。

crypto-js支持的填充方式:Pkcs7、Iso97971、AnsiX923、Iso10126、ZeroPadding、NoPadding。

当不传入模式、填充、偏移量时,会默认使用CBC加密模式、Pkcs7填充方式和一个随机生成的偏移量。

ECB模式不需要偏移量。

const word: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse("Message") // 使用Utf8格式解析明文 
const key: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse("key") // 使用Utf8格式解析密钥 
const iv: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse('iv') // 使用Utf8格式解析偏移量 
// DES加密,可以配置加密模式、填充方式和偏移量 
let desOutput CryptoJS.DES.encrypt(word, key, { 
    mode: CryptoJS.mode.CBC, 
    padding: CryptoJS.pad.Pkcs7, 
    iv: iv 
}).ciphertext.toString()
  • 一次性解密

@ohos/crypto-js只能解密格式为Base64的密文,如果密文是其他格式,需要先转换成Base64。

解密返回的结果必须用Utf8格式转为明文。

// 使用hex格式解析密文,并转为Base64格式,如果密文已经是Base64格式则不需要转换 
let word: CryptoJS.lib.WordArray | string = CryptoJS.enc.Hex.parse("ciphertext") 
word = CryptoJS.enc.Base64.stringify(word) 
const key: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse("key") // 使用Utf8格式解析密钥 
const iv: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse('iv') // 使用Utf8格式解析偏移量 
// DES解密,需要配置与加密一致的加密模式、填充方式和偏移量 
let desDecryptOutput = CryptoJS.DES.decrypt(word, key, { 
    mode: CryptoJS.mode.CBC, 
    padding: CryptoJS.pad.Pkcs7, 
    iv: iv 
}).toString(CryptoJS.enc.Utf8) // 将解密结果转为utf8格式才能正确显示
  • 分段加密

调用CryptoJS.algo.DES.createEncryptor接口,配置密钥、模式、填充、偏移量创建DES加密算法对象,调用process方法传入分段明文WordArray对象生成分段密文WordArray对象,通过数组克隆与拼接操作生成完整密文。

let word1: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse("plaintext1") 
let word2: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse("plaintext2") 
let word3: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse("plaintext3") 
const key: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse("key") 
const iv: CryptoJS.lib.WordArray = CryptoJS.enc.Utf8.parse('iv') 
 
// 创建DES加密实例,配置加密模式、填充方式和偏移量 
let desEncrypt = CryptoJS.algo.DES.createEncryptor(key, { 
    mode: CryptoJS.mode.CBC, 
    padding: CryptoJS.pad.Pkcs7, 
    iv: iv 
}) 
 
// 分段传入明文 
const desEncryptOutput1 = desEncrypt.process(word1) 
const desEncryptOutput2 = desEncrypt.process(word2) 
const desEncryptOutput3 = desEncrypt.process(word3) 
const desEncryptOutput4 = desEncrypt.finalize() 
 
// 拼接加密结果 默认为Hex格式 
let desEncryptOutput = desEncryptOutput1.clone() 
.concat(desEncryptOutput2) 
.concat(desEncryptOutput3) 
.concat(desEncryptOutput4) 
.toString()
  • 分段解密

调用CryptoJS.algo.DES.createDecryptor接口,配置密钥、模式、填充、偏移量创建DES解密算法对象,调用process方法传入分段密文WordArray对象生成分段明文WordArray对象,通过数组克隆与拼接操作生成完整明文,并转为utf8格式显示。

// 使用对应格式解析密文 
const plaintextWordArray: CryptoJS.lib.WordArray = CryptoJS.enc.Hex.parse(desEncryptOutput) 
let segments: CryptoJS.lib.WordArray[] = [] 
let offset = 0 
let length = plaintextWordArray.sigBytes 
let segmentSize = 8 
 
// 对密文分段 
while (offset < length) { 
    let clone = plaintextWordArray.clone() 
    clone.clamp()  // 清除多余的字节 
    // 确保分段不会超出消息的末尾 
    let size = Math.min(segmentSize, length - offset) 
    clone.sigBytes = size 
    // 截取分段 
    segments.push(clone) 
    // 移动到下一个分段 
    offset += segmentSize 
    plaintextWordArray.words.splice(0, size / 4) // 每个字的大小是4字节 
    plaintextWordArray.sigBytes -= size 
} 
 
// 创建DES解密实例,配置加密模式、填充方式和偏移量 
let desDecrypt = CryptoJS.algo.DES.createDecryptor(key, { 
    mode: CryptoJS.mode.CBC, 
    padding: CryptoJS.pad.Pkcs7, 
    iv: iv 
}) 
 
// 创建一个空WordArray 
let ciphertextWordArray: CryptoJS.lib.WordArray = CryptoJS.lib.WordArray.create() 
// 分段解密,同时拼接结果 
for (let word of segments) { 
    let segmentOutput = desDecrypt.process(word) 
    ciphertextWordArray.concat(segmentOutput) 
} 
let finalizeOutput = desDecrypt.finalize() 
ciphertextWordArray.concat(finalizeOutput) 
// 将明文转回Utf8格式 
let desDecryptOutput = ciphertextWordArray.toString(CryptoJS.enc.Utf8)


分类
收藏
回复
举报
回复
    相关推荐