在 Node.js (PBKDF2WithHmacSHA1) 中重写 Java AES 256 GCM 加密
Rewriting Java AES 256 GCM Encryption in Node.js (PBKDF2WithHmacSHA1)
我在 java 中有以下代码用于加密纯文本:
private static final String SECRET_KEY = "SecKeyTest";
private static final String SALT = "thisIsSalt";
public String encrypt(String strToEncrypt) {
try {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALT.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128 , iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
我必须使用 NodeJs 重写相同的内容,到目前为止我所做的:
const salt = "thisIsSalt";
const digest = 'sha256';
const aesSecretKey = "SecKeyTest";
module.exports = {
encrypt: function (plainText){
const key = crypto.pbkdf2Sync(aesSecretKey, salt, 65536, 32, digest); //key len 32bytes i.e 256bits
const iv = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]);
// AES 256 GCM Mode
var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
// encrypt the given text
var encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);
// extract the auth tag
var tag = cipher.getAuthTag();
// generate output
return Buffer.concat([Buffer.from(salt), iv, tag, encrypted]).toString('base64');
}
};
对于输入:“你好”:
Java: rgCx2SDSqio15M+0lViNAzW/lUmz
节点:dGhpc0lzU2FsdAAAAAAAAAAAAAAAAAAAAADSqio15M+0lViNAzW/lUmzrgCx2SA=
Java 代码按此顺序隐式连接密文和标签。因此,要在 NodeJS 代码中获得相同的结果,需要进行以下更改:
return Buffer.concat([encrypted, tag]).toString('base64');
但是salt和IV不应该是静态的,而是应该在每次密钥推导和加密时随机生成。由于解密需要 salt 和 IV,并且两者都不是秘密的,因此它们与密文和标签一起传递,通常也连接在一起,例如:salt |四 |密文 |标签。
我在 java 中有以下代码用于加密纯文本:
private static final String SECRET_KEY = "SecKeyTest";
private static final String SALT = "thisIsSalt";
public String encrypt(String strToEncrypt) {
try {
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALT.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128 , iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
我必须使用 NodeJs 重写相同的内容,到目前为止我所做的:
const salt = "thisIsSalt";
const digest = 'sha256';
const aesSecretKey = "SecKeyTest";
module.exports = {
encrypt: function (plainText){
const key = crypto.pbkdf2Sync(aesSecretKey, salt, 65536, 32, digest); //key len 32bytes i.e 256bits
const iv = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]);
// AES 256 GCM Mode
var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
// encrypt the given text
var encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);
// extract the auth tag
var tag = cipher.getAuthTag();
// generate output
return Buffer.concat([Buffer.from(salt), iv, tag, encrypted]).toString('base64');
}
};
对于输入:“你好”:
Java: rgCx2SDSqio15M+0lViNAzW/lUmz
节点:dGhpc0lzU2FsdAAAAAAAAAAAAAAAAAAAAADSqio15M+0lViNAzW/lUmzrgCx2SA=
Java 代码按此顺序隐式连接密文和标签。因此,要在 NodeJS 代码中获得相同的结果,需要进行以下更改:
return Buffer.concat([encrypted, tag]).toString('base64');
但是salt和IV不应该是静态的,而是应该在每次密钥推导和加密时随机生成。由于解密需要 salt 和 IV,并且两者都不是秘密的,因此它们与密文和标签一起传递,通常也连接在一起,例如:salt |四 |密文 |标签。