Typescript 中的加密 ( Angular ) 和 Java 中的解密
Encryption in Typescript ( Angular ) and Decryption in Java
我目前正在使用 Angular7。
我有 Java 客户端提供的加密、解密代码,我需要在 Angular.
下面是 Java.
的代码
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
里面Class我有
class EnDc(String passPhrase)
{
private static final byte[] SALT = { 8 random numbers between -127 to 127 };
private static final int ITERATION_COUNT = 1000;
private static final int KEY_LENGTH = 256;
private static final int IV_LENGTH = 16;
private Cipher eCipher;
private Cipher dCipher;
private byte[] encrypt;
private byte[] iv;
哈希密钥和iv的生成如下:
SecretKeyFactory secretKeyFactory =
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), SALT,
1000, 256);
他们已经使用密钥规范生成了临时密钥,如下所示:
secretKeyTemp = secretKeyFactory.generateSecret(keySpec);
使用临时密钥和 "AES"
生成了新密钥
secretKey = new SecretKeySpec(secretKeyTemp.getEncoded(), //encode
"AES");
后续步骤:
this.eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
this.eCipher.init(1, secretKey);
// 1 - ENCRYPT_MODE, 2 - DECRYPT_MODE
第四代:
this.iv = ((IvParameterSpec)this.eCipher.getParameters().getParameterSpec(IvParameterSpec.class)).getIV();
}
实际加密函数如下
public String encrypt(String encrypt)
{
String encStr = null;
try
{
byte[] bytes = encrypt.getBytes("UTF8");
byte[] encrypted = encrypt(bytes);
byte[] cipherText = new byte[encrypted.length + this.iv.length];
System.arraycopy(this.iv, 0, cipherText, 0, this.iv.length);
System.arraycopy(encrypted, 0, cipherText, this.iv.length, encrypted.length);
encStr = new String(Base64.getEncoder().encode(cipherText));
}
catch (Exception ex)
{
ex.printStackTrace();
}
return encStr;
}
我正在尝试在 Angular 的服务文件中实现这个,根据我的理解,SALT 字节数组是预定义的,IV 是随机的,它附加在加密字符串之前并在解密时提取,
所以我尝试的 JS 方式如下
import * as CryptoJS from 'crypto-js';
encrypt (msg, pass) {
const salt = CryptoJS.lib.WordArray.random(128 / 8);
const key = CryptoJS.PBKDF2( pass, salt, {
keySize: this.keySize / 32,
iterations: this.iterations
});
const iv = CryptoJS.lib.WordArray.random(128 / 8);
const encrypted = CryptoJS.AES.encrypt(msg, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
const transitmessage = salt.toString() + iv.toString() + encrypted.toString();
return transitmessage;
}
所以,我已经完成了 link http://www.adonespitogo.com/articles/encrypting-data-with-cryptojs-aes/ 中的这段代码,所以现在的问题是如何实现硬编码在 JAVA 以及 [=60] 中的 SALT =] 代码他们没有发送带有加密字符串的盐密钥,但 IV 仅作为前 16 位。我该如何实施?
我试过这样做
salt = CryptoJS.lib.WordArray.create([-67, -85, 13, -28, 75, 112, -126, 103]);
但生成的密钥是对象,而且我在解密时遇到错误
编辑 1:我希望 salt 每次都相同,我当前随机生成并附加到加密字符串。
我不知道 Javascript
是否有一些 SecretKeyFactory 和 Keyspec 的实现
感谢帮助,提前致谢。
当您执行以下操作时,WordArray.create
方法将您的数字用作 32 位整数:
salt = CryptoJS.lib.WordArray.create([-67, -85, 13, -28, 75, 112, -126, 103]);
在这种情况下,您的十六进制盐是:
ffffffbdffffffab0000000dffffffe40000004b00000070ffffff8200000067
如果将 javascript Array
对象转换为 Int8Array
,CryptoJS 将创建与 Java:
中相同的盐
salt = CryptoJS.lib.WordArray.create(new Int8Array([-67, -85, 13, -28, 75, 112, -126, 103]));
结果:
bdab0de44b708267
如果适合您,请查找以下解决方案。
encrypt (msg, pass) {
const key = CryptoJS.PBKDF2(pass, this.salt, {
keySize: this.keySize / 32,
iterations: this.iterations
});
const iv = CryptoJS.lib.WordArray.random(128 / 8);
const encrypted = CryptoJS.AES.encrypt(msg, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
const transitmessage = iv + encrypted.ciphertext;
var tm=CryptoJS.enc.Hex.parse(transitmessage); // This converts to Type Word which is required for below function as input
return CryptoJS.enc.Base64.stringify(tm); // Encoding
}
我目前正在使用 Angular7。 我有 Java 客户端提供的加密、解密代码,我需要在 Angular.
下面是 Java.
的代码import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
里面Class我有
class EnDc(String passPhrase)
{
private static final byte[] SALT = { 8 random numbers between -127 to 127 };
private static final int ITERATION_COUNT = 1000;
private static final int KEY_LENGTH = 256;
private static final int IV_LENGTH = 16;
private Cipher eCipher;
private Cipher dCipher;
private byte[] encrypt;
private byte[] iv;
哈希密钥和iv的生成如下:
SecretKeyFactory secretKeyFactory =
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), SALT,
1000, 256);
他们已经使用密钥规范生成了临时密钥,如下所示:
secretKeyTemp = secretKeyFactory.generateSecret(keySpec);
使用临时密钥和 "AES"
生成了新密钥 secretKey = new SecretKeySpec(secretKeyTemp.getEncoded(), //encode
"AES");
后续步骤:
this.eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
this.eCipher.init(1, secretKey);
// 1 - ENCRYPT_MODE, 2 - DECRYPT_MODE
第四代:
this.iv = ((IvParameterSpec)this.eCipher.getParameters().getParameterSpec(IvParameterSpec.class)).getIV();
}
实际加密函数如下
public String encrypt(String encrypt)
{
String encStr = null;
try
{
byte[] bytes = encrypt.getBytes("UTF8");
byte[] encrypted = encrypt(bytes);
byte[] cipherText = new byte[encrypted.length + this.iv.length];
System.arraycopy(this.iv, 0, cipherText, 0, this.iv.length);
System.arraycopy(encrypted, 0, cipherText, this.iv.length, encrypted.length);
encStr = new String(Base64.getEncoder().encode(cipherText));
}
catch (Exception ex)
{
ex.printStackTrace();
}
return encStr;
}
我正在尝试在 Angular 的服务文件中实现这个,根据我的理解,SALT 字节数组是预定义的,IV 是随机的,它附加在加密字符串之前并在解密时提取,
所以我尝试的 JS 方式如下
import * as CryptoJS from 'crypto-js';
encrypt (msg, pass) {
const salt = CryptoJS.lib.WordArray.random(128 / 8);
const key = CryptoJS.PBKDF2( pass, salt, {
keySize: this.keySize / 32,
iterations: this.iterations
});
const iv = CryptoJS.lib.WordArray.random(128 / 8);
const encrypted = CryptoJS.AES.encrypt(msg, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
const transitmessage = salt.toString() + iv.toString() + encrypted.toString();
return transitmessage;
}
所以,我已经完成了 link http://www.adonespitogo.com/articles/encrypting-data-with-cryptojs-aes/ 中的这段代码,所以现在的问题是如何实现硬编码在 JAVA 以及 [=60] 中的 SALT =] 代码他们没有发送带有加密字符串的盐密钥,但 IV 仅作为前 16 位。我该如何实施?
我试过这样做
salt = CryptoJS.lib.WordArray.create([-67, -85, 13, -28, 75, 112, -126, 103]);
但生成的密钥是对象,而且我在解密时遇到错误
编辑 1:我希望 salt 每次都相同,我当前随机生成并附加到加密字符串。
我不知道 Javascript
是否有一些 SecretKeyFactory 和 Keyspec 的实现感谢帮助,提前致谢。
当您执行以下操作时,WordArray.create
方法将您的数字用作 32 位整数:
salt = CryptoJS.lib.WordArray.create([-67, -85, 13, -28, 75, 112, -126, 103]);
在这种情况下,您的十六进制盐是:
ffffffbdffffffab0000000dffffffe40000004b00000070ffffff8200000067
如果将 javascript Array
对象转换为 Int8Array
,CryptoJS 将创建与 Java:
salt = CryptoJS.lib.WordArray.create(new Int8Array([-67, -85, 13, -28, 75, 112, -126, 103]));
结果:
bdab0de44b708267
如果适合您,请查找以下解决方案。
encrypt (msg, pass) {
const key = CryptoJS.PBKDF2(pass, this.salt, {
keySize: this.keySize / 32,
iterations: this.iterations
});
const iv = CryptoJS.lib.WordArray.random(128 / 8);
const encrypted = CryptoJS.AES.encrypt(msg, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
});
const transitmessage = iv + encrypted.ciphertext;
var tm=CryptoJS.enc.Hex.parse(transitmessage); // This converts to Type Word which is required for below function as input
return CryptoJS.enc.Base64.stringify(tm); // Encoding
}