Files
base-golang/pkg/crypto/client/crypto/aes.ts
T
2026-02-07 15:38:01 +08:00

91 lines
2.0 KiB
TypeScript

import { IEncryptor } from './interface';
/**
* AES-GCM加密器
*/
export class AESEncryptor implements IEncryptor {
private key: CryptoKey | null = null;
constructor(keyString: string) {
this.importKey(keyString);
}
/**
* 导入密钥
*/
private async importKey(keyString: string): Promise<void> {
const encoder = new TextEncoder();
const keyData = encoder.encode(keyString.padEnd(32, '0').substring(0, 32));
this.key = await crypto.subtle.importKey(
'raw',
keyData,
{
name: 'AES-GCM',
length: 256,
},
false,
['encrypt', 'decrypt']
);
}
/**
* 加密数据
*/
async encrypt(plaintext: Uint8Array): Promise<Uint8Array> {
if (!this.key) {
throw new Error('密钥未设置');
}
// 生成随机IV
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: iv,
},
this.key,
plaintext
);
// 将IV和密文拼接在一起
const result = new Uint8Array(iv.length + encrypted.byteLength);
result.set(iv, 0);
result.set(new Uint8Array(encrypted), iv.length);
return result;
}
/**
* 解密数据
*/
async decrypt(ciphertext: Uint8Array): Promise<Uint8Array> {
if (!this.key) {
throw new Error('密钥未设置');
}
// 提取IV
const iv = ciphertext.slice(0, 12);
const data = ciphertext.slice(12);
const decrypted = await crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: iv,
},
this.key,
data
);
return new Uint8Array(decrypted);
}
/**
* 返回算法名称
*/
name(): string {
return 'AES-GCM-256';
}
}