CryptoJS AES 解密返回空白值 - 打字稿
CrytoJS AES decrypt returning a blank value - Typescript
我有以下 Typescript 代码并尝试了一些方法,但我无法使解密工作。将不胜感激。
提前致谢!
import {Injectable} from '@angular/core';
import * as CryptoJS from 'crypto-js';
@Injectable({
providedIn: 'root'
})
export class UmCryptoService {
constructor() {
}
encrypt<T>(key, value: T): string{
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const ciphertext = CryptoJS.AES.encrypt(JSON.stringify(value), key, {iv: i}).toString();
console.log('SS cipherText: ' + ciphertext);
return ciphertext;
}
decrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const decryptedData = CryptoJS.AES.decrypt(CryptoJS.enc.Base64.parse(value), key, {iv: i});
console.log('SS utf8 decryptedData: ' + decryptedData.toString(CryptoJS.enc.Utf8));
return decryptedData.toString(CryptoJS.enc.Utf8);
}
}
在控制台中,我看到:
LOG: 'SS cipherText: UbNlnYr0qd7ua0TcPTMIyxItPNvNscCfQYIP244Mt/5e7vPHZ1cFDWE9XgV7pA6a'
LOG: 'SS utf8 decryptedData: '
这里有几个单元测试:
it('should encrypt string value', () => {
const key = '1234567890987654321';
const strValue = 'Hey check out this encryption!';
const cipher = service.encrypt(key, strValue);
console.log('SS: cipher str: ' + cipher);
expect(cipher).toBeDefined();
);
});
fit('should decrypt cipher', fakeAsync (() => {
const key = '1234567890987654321';
const cipher = 'UbNlnYr0qd7ua0TcPTMIyxItPNvNscCfQYIP244Mt/5e7vPHZ1cFDWE9XgV7pA6a';
const strValue = service.decrypt(key, cipher);
tick(100000);
console.log('SS: strValue: ' + strValue);
expect(strValue).toBeDefined();
}));
密文必须作为 CipherParams
对象或 Base64 编码字符串 (s. The Cipher Input) 传递给 CryptoJS.AES.decrypt()
,而不是作为实际代码中的 WordArray
(假设 decrypt()
中的 value
是 encrypt()
的 return 值),即可能的修复是:
const decryptedData = CryptoJS.AES.decrypt(value, key, {iv: i});
完整代码:
function encrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const ciphertext = CryptoJS.AES.encrypt(JSON.stringify(value), key, {iv: i}).toString();
//console.log('SS cipherText: ' + ciphertext);
document.getElementById("ct").innerHTML = 'SS cipherText: ' + ciphertext;
return ciphertext;
}
function decrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const decryptedData = CryptoJS.AES.decrypt(value, key, {iv: i}); // Fix: pass Base64 encoded ciphertext
//console.log('SS utf8 decryptedData: ' + decryptedData.toString(CryptoJS.enc.Utf8));
document.getElementById("dt").innerHTML = 'SS utf8 decryptedData: ' + decryptedData.toString(CryptoJS.enc.Utf8);
return decryptedData.toString(CryptoJS.enc.Utf8);
}
var key = '01234567890123456789012345678901';
var ct = encrypt(key, {test: 'The quick brown fox jumps over the lazy dog'});
var dt = decrypt(key, ct);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<p style="font-family:'Courier New', monospace;" id="ct"></p>
<p style="font-family:'Courier New', monospace;" id="dt"></p>
请注意,发布的单元测试不适合测试有问题的代码片段,因为在单元测试中 key
作为字符串传递,因此 built-in 密钥派生 被使用,而在代码片段中 key
作为 WordArray
传递,因此密钥被 直接应用 (s. The Cipher Input).所以底层逻辑非常不同。
另外,静态 IV 是不安全的。 (non-secret) IV 应该是 随机 为 each 加密生成并与密文一起传递给解密方 - 通常是串联的。
我有以下 Typescript 代码并尝试了一些方法,但我无法使解密工作。将不胜感激。
提前致谢!
import {Injectable} from '@angular/core';
import * as CryptoJS from 'crypto-js';
@Injectable({
providedIn: 'root'
})
export class UmCryptoService {
constructor() {
}
encrypt<T>(key, value: T): string{
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const ciphertext = CryptoJS.AES.encrypt(JSON.stringify(value), key, {iv: i}).toString();
console.log('SS cipherText: ' + ciphertext);
return ciphertext;
}
decrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const decryptedData = CryptoJS.AES.decrypt(CryptoJS.enc.Base64.parse(value), key, {iv: i});
console.log('SS utf8 decryptedData: ' + decryptedData.toString(CryptoJS.enc.Utf8));
return decryptedData.toString(CryptoJS.enc.Utf8);
}
}
在控制台中,我看到:
LOG: 'SS cipherText: UbNlnYr0qd7ua0TcPTMIyxItPNvNscCfQYIP244Mt/5e7vPHZ1cFDWE9XgV7pA6a'
LOG: 'SS utf8 decryptedData: '
这里有几个单元测试:
it('should encrypt string value', () => {
const key = '1234567890987654321';
const strValue = 'Hey check out this encryption!';
const cipher = service.encrypt(key, strValue);
console.log('SS: cipher str: ' + cipher);
expect(cipher).toBeDefined();
);
});
fit('should decrypt cipher', fakeAsync (() => {
const key = '1234567890987654321';
const cipher = 'UbNlnYr0qd7ua0TcPTMIyxItPNvNscCfQYIP244Mt/5e7vPHZ1cFDWE9XgV7pA6a';
const strValue = service.decrypt(key, cipher);
tick(100000);
console.log('SS: strValue: ' + strValue);
expect(strValue).toBeDefined();
}));
密文必须作为 CipherParams
对象或 Base64 编码字符串 (s. The Cipher Input) 传递给 CryptoJS.AES.decrypt()
,而不是作为实际代码中的 WordArray
(假设 decrypt()
中的 value
是 encrypt()
的 return 值),即可能的修复是:
const decryptedData = CryptoJS.AES.decrypt(value, key, {iv: i});
完整代码:
function encrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const ciphertext = CryptoJS.AES.encrypt(JSON.stringify(value), key, {iv: i}).toString();
//console.log('SS cipherText: ' + ciphertext);
document.getElementById("ct").innerHTML = 'SS cipherText: ' + ciphertext;
return ciphertext;
}
function decrypt(key, value){
key = CryptoJS.enc.Utf8.parse(key);
const i = CryptoJS.enc.Utf8.parse('1583288699248111');
const decryptedData = CryptoJS.AES.decrypt(value, key, {iv: i}); // Fix: pass Base64 encoded ciphertext
//console.log('SS utf8 decryptedData: ' + decryptedData.toString(CryptoJS.enc.Utf8));
document.getElementById("dt").innerHTML = 'SS utf8 decryptedData: ' + decryptedData.toString(CryptoJS.enc.Utf8);
return decryptedData.toString(CryptoJS.enc.Utf8);
}
var key = '01234567890123456789012345678901';
var ct = encrypt(key, {test: 'The quick brown fox jumps over the lazy dog'});
var dt = decrypt(key, ct);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<p style="font-family:'Courier New', monospace;" id="ct"></p>
<p style="font-family:'Courier New', monospace;" id="dt"></p>
请注意,发布的单元测试不适合测试有问题的代码片段,因为在单元测试中 key
作为字符串传递,因此 built-in 密钥派生 被使用,而在代码片段中 key
作为 WordArray
传递,因此密钥被 直接应用 (s. The Cipher Input).所以底层逻辑非常不同。
另外,静态 IV 是不安全的。 (non-secret) IV 应该是 随机 为 each 加密生成并与密文一起传递给解密方 - 通常是串联的。