加密
鸿蒙中常用的加密解密的工具
文档
使用AES对称密钥(ECB模式)加解密(ArkTS)-加解密开发指导-加解密
前置
- 加密分为
对称加密
和非对称加密
- 一般来说你要加密,大体的用什么加密你是知道的(比如AES、DES、RSA、MD5.....),但是还应该了解具体的加密规则:
加密算法
、分组模式
、密钥长度
、填充模式
。
- 以AES加密为例,密钥长度128,常用分组模式为ECB,使用PKCS7填充模式,加密规则的字符串参数则为
AES128|ECB|PKCS7
(后面加密要用到)
加密步骤
- 处理加密key:我们的原始密钥key一般为一定长度的字符串,在使用前需要将其转换为符合要求的Key。
- 将原始key转换为二进制字节数组类型
- 根据密钥长度判断是否满足长度,不足的按规则补齐,过长需要裁切(也可以使用工具中的convertKey)
- 将转换后的key包装成需要的格式(如DataBolb)
- 创建加密生成器实例,如下(有些工具内置了加密实例,可以直接按加密方法调用对应加密方法)
let cipherAlgName = 'AES128|ECB|PKCS7'; let cipher = cryptoFramework.createCipher(cipherAlgName);
- 调用初始化方法
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null);
- 调用加密方法
let cipherData = await cipher.doFinal(plainText);
- (可能需要)将密文转换为其他格式(如Base64)来方便发送
示例
1、示例1
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer, util } from '@kit.ArkTS';
@Entry
@Component
struct AESEncryptionDecryption {
build() {
Row() {
Button('加解密')
.onClick(async () => {
// 导入密钥
let key = await getKey();
// 加密
let globalResult = await aesEncrypt('测试', key);
// 解密
aesDecrypt(globalResult, key);
})
.width('100%')
.height(50)
}
.height('100%')
}
}
export const base = new util.Base64Helper();
// 字节流转成可理解的字符串
export function uint8ArrayToString(array: Uint8Array) {
// 将UTF-8编码转换成Unicode编码
let out: string = '';
let index: number = 0;
let len: number = array.length;
while (index < len) {
let character = array[index++];
switch (character >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
out += String.fromCharCode(character);
break;
case 12:
case 13:
out += String.fromCharCode(((character & 0x1F) << 6) | (array[index++] & 0x3F));
break;
case 14:
out += String.fromCharCode(((character & 0x0F) << 12) | ((array[index++] & 0x3F) << 6) |
((array[index++] & 0x3F) << 0));
break;
default:
break;
}
}
return out;
}
// 字符串转成字节流
function stringToUint8Array(str: string) {
return new Uint8Array(buffer.from(str, 'utf-8').buffer);
}
// 获取密钥
async function getKey() {
let symAlgName = 'AES128';
let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
let dataUint8Array = stringToUint8Array('Whh82GtW/EVjBkD8');
let keyBlob: cryptoFramework.DataBlob = { data: dataUint8Array };
let promiseSymKey = await symKeyGenerator.convertKey(keyBlob);
let key = base.encodeToStringSync(promiseSymKey.getEncoded().data); // 将密钥转换为base64存储
return key;
}
// 加密
async function aesEncrypt(text: string, puKey: string): Promise<string> {
let globalResult = '';
try {
let cipherAlgName = 'AES128|ECB|PKCS7';
let globalCipher = cryptoFramework.createCipher(cipherAlgName);
let symAlgName = 'AES128';
let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
let dataUint8Array = base.decodeSync(puKey);
let keyBlob: cryptoFramework.DataBlob = { data: dataUint8Array };
let promiseSymKey = await symKeyGenerator.convertKey(keyBlob);
await globalCipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, promiseSymKey, null);
let result = await globalCipher.doFinal({ data: stringToUint8Array(text) });
globalResult = base.encodeToStringSync(result.data);
console.info('加密后的明文:' + globalResult);
} catch (err) {
console.info(err.message);
}
return globalResult;
}
// 解密
async function aesDecrypt(text: string, key: string) {
let globalResult = '';
try {
let cipherAlgName = 'AES128|ECB|PKCS7';
let globalCipher = cryptoFramework.createCipher(cipherAlgName);
let symAlgName = 'AES128';
let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
let dataUint8Array = base.decodeSync(key);
let keyBlob: cryptoFramework.DataBlob = { data: dataUint8Array };
let promiseSymKey = await symKeyGenerator.convertKey(keyBlob);
await globalCipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, promiseSymKey, null);
let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(text) };
let result = await globalCipher.doFinal(plainText);
globalResult = uint8ArrayToString(result.data);
console.info('解密后的明文:' + globalResult);
} catch (err) {
console.info(err.message);
}
}
2、示例2
import { util } from '@kit.ArkTS';
import { CryptoJS } from '@ohos/crypto-js';
import { CryptoHelper, CryptoUtil, DES, Base64Util, StrUtil } from '@pura/harmony-utils';
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = 'Base64DES';
export class Base64DES {
static socketEncrypt(encryptString: string, keyStr?: string) {
try {
keyStr = 'abcdefg123456789';
// let key: Uint8Array = Base64DES.createDESKey(StrUtil.strToUint8Array(keyStr));
const key = CryptoJS.enc.Utf8.parse(keyStr.slice(0, 8));
const result = CryptoJS.DES.encrypt(CryptoJS.enc.Utf8.parse(encryptString), key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return result.toString();
} catch (err) {
let error: BusinessError = err as BusinessError;
console.log(TAG, JSON.stringify(error));
return ''
}
}
//字符串转Uint8Array
static getBytes(str: string): Uint8Array {
//TextEncoder默认使用"utf-8"编码
const textEncoder: util.TextEncoder = new util.TextEncoder();
return textEncoder.encodeInto(str);
}
static createDESKey(key: Uint8Array): Uint8Array {
// DES 密钥必须是 8 字节长
if (key.length < 8) {
// 如果密钥过短,进行填充
key = CryptoHelper.getUint8ArrayPaddingZero(key, 8);
} else if (key.length > 8) {
// 如果密钥过长,进行截断
key = key.slice(0, 8);
}
return key;
}
}