81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
|
||
import * as CryptoJS from 'crypto-js'
|
||
|
||
const SIGN_BYTES_LEN = 16
|
||
|
||
const CRYPTO_SECRET_KEY_MAP = {
|
||
local: 'asdb2l0jskjft1q314f3ffjy71k9shj6',
|
||
development: 'asdb2l0jskjft1q314f3ffjy71k9shj6',
|
||
pre: 'asdb2l0jskjft1q314f3ffjy71k9shj6',
|
||
production: 'asdb2l0jskjft1q314f3ffjy71k9shj6',
|
||
} as Record<string, string>
|
||
|
||
export class AESUtils {
|
||
private secretKey: string
|
||
constructor(env?: string) {
|
||
// Default to production key if env is missing, matching the logic
|
||
this.secretKey = CRYPTO_SECRET_KEY_MAP[env || 'production']
|
||
}
|
||
|
||
private get getSecretKey() {
|
||
return CryptoJS.enc.Utf8.parse(this.secretKey)
|
||
}
|
||
|
||
decryptAES_CBC(ciphertext: string): string {
|
||
const secretKey = this.getSecretKey
|
||
try {
|
||
// 将 URL 安全的 Base64 编码的密文解码
|
||
const ciphertextBytes = CryptoJS.enc.Base64.parse(
|
||
ciphertext.replace(/-/g, '+').replace(/_/g, '/'),
|
||
)
|
||
|
||
// 从密文中提取 IV(前 16 字节)
|
||
const iv = ciphertextBytes.clone()
|
||
iv.sigBytes = SIGN_BYTES_LEN
|
||
iv.clamp()
|
||
|
||
// 从密文中提取实际的加密数据
|
||
const encryptedContent = ciphertextBytes.clone()
|
||
encryptedContent.words.splice(0, SIGN_BYTES_LEN / 4) // 移除前 16 字节(IV)
|
||
encryptedContent.sigBytes -= SIGN_BYTES_LEN
|
||
|
||
// 执行解密
|
||
const decrypted = CryptoJS.AES.decrypt(
|
||
{ ciphertext: encryptedContent } as any,
|
||
secretKey,
|
||
{
|
||
iv,
|
||
mode: CryptoJS.mode.CBC,
|
||
padding: CryptoJS.pad.Pkcs7,
|
||
},
|
||
)
|
||
|
||
// 将解密结果转换为 UTF-8 字符串
|
||
return decrypted.toString(CryptoJS.enc.Utf8)
|
||
} catch (e) {
|
||
console.error(e)
|
||
throw new Error('解密失败')
|
||
}
|
||
}
|
||
|
||
// Included purely for completeness if needed later
|
||
encryptAES_CBC(data: string): string {
|
||
const secretKey = this.getSecretKey
|
||
try {
|
||
const iv = CryptoJS.lib.WordArray.random(SIGN_BYTES_LEN)
|
||
const encrypted = CryptoJS.AES.encrypt(data, secretKey, {
|
||
iv,
|
||
mode: CryptoJS.mode.CBC,
|
||
padding: CryptoJS.pad.Pkcs7,
|
||
})
|
||
|
||
// 将 IV 和密文连接,然后进行 Base64 编码
|
||
const result = iv.concat(encrypted.ciphertext)
|
||
return CryptoJS.enc.Base64.stringify(result)
|
||
} catch (e) {
|
||
console.error(e)
|
||
throw new Error('加密失败')
|
||
}
|
||
}
|
||
}
|