Java/Node 使用盐和迭代计数的用户密码的 PBKDF2 哈希 - 等效节点
Java/Node PBKDF2 hash of the user password using the salt and the iteration count - Node Equivalent
我正在尝试在 Nodejs 中复制此方法。我想知道它在 Node 中的等价物类似于 .
Java代码:
private final byte[] _createSaltedPassword(String password, byte[] salt, int iterationCount) {
byte[] dk;
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, 256);
SecretKeyFactory key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
dk = key.generateSecret(keySpec).getEncoded();
return dk;
}
为了这个示例,我保持用户 (user)、客户端随机数 (aabbccddaabbccdd)、密码 (Password123)、salt 和迭代计数 (4096) 相同。我最后一次尝试使用加密在 Node 中获得等效项。
const crypto = require("crypto");
const saltedPassword = crypto.pbkdf2Sync(password, salt, iterationCount, 32, 'sha256').toString('base64');
console.log('Salted Password:', saltedPassword);
用于摘要式身份验证。来自 Java 程序的输出日志:
Output log from Java program
Java 加盐密码: nA0hWFpZshs+iME/leUy+e2gM5mjIgo6PYJ8eNjRdhY=
节点加盐密码:PYgn6rcngiE0HSMwzmWhd2W5qTdaRilw4PEeuy3OyRo=
谢谢。
抱歉懒得查看链接代码,但我提供了两个示例 Java 和带有加密库的 NodeJS,它们使用 PBKDF2 算法从密码短语生成密钥。您可以 运行 在在线编译器中使用这两种代码 - Java code and NodeJs code.
这是带有 fixed = unsecure salt 的输出:
Generate a 32 byte long AES key with PBKDF2
aesKeySha256 length: 32 data: e1ea3e4b0376c0f9bf93b94fe71719a099317297b79108aacd88c8a355d7a3d4
安全警告:以下代码没有任何异常处理,仅供学习使用。不要使用
固定盐在生产中,它仅用于显示两个平台生成相同的密钥。
Java代码:
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("Generate a 32 byte long AES key with PBKDF2");
// get the password as char array
char[] passwordChar = "secret password".toCharArray();
final int PBKDF2_ITERATIONS = 15000; // number of iterations, higher is better but slower
// ### security warning - never use a fixed salt in production, this is for compare reasons only
byte[] salt = generateFixedSalt32Byte();
// please use below generateSalt32Byte()
//byte[] salt = generateSalt32Byte();
byte[] aesKeySha256 = generateAes256KeyPbkdf2Sha256(passwordChar, PBKDF2_ITERATIONS, salt);
System.out.println("aesKeySha256 length: " + aesKeySha256.length + " data: " + bytesToHex(aesKeySha256));
}
public static byte[] generateAes256KeyPbkdf2Sha256(char[] password, int iterations, byte[] salt) throws Exception {
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec keySpec = new PBEKeySpec(password, salt, iterations, 32 * 8);
return secretKeyFactory.generateSecret(keySpec).getEncoded();
}
private static byte[] generateSalt32Byte() {
SecureRandom secureRandom = new SecureRandom();
byte[] salt = new byte[32];
secureRandom.nextBytes(salt);
return salt;
}
private static byte[] generateFixedSalt32Byte() {
// ### security warning - never use this in production ###
byte[] salt = new byte[32]; // 32 x0's
return salt;
}
private static String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
return result.toString();
}
}
NodeJs 代码
console.log("Generate a 32 byte long AES key with PBKDF2");
var crypto = require('crypto');
var password = "secret password";
var PBKDF2_ITERATIONS = 15000; // number of iterations, higher is better but slower
// ### security warning - never use a fixed salt in production, this is for compare reasons only
var salt = generateFixedSalt32Byte();
// please use below generateSalt32Byte()
//var salt = generateSalt32Byte();
var aesKeySha256 = generateAes256KeyPbkdf2Sha256(password, PBKDF2_ITERATIONS, salt);
console.log('aesKeySha256 length: ',
aesKeySha256.length, ' data: ', bytesToHex(aesKeySha256));
function generateAes256KeyPbkdf2Sha256(password, iterations, salt) {
return crypto.pbkdf2Sync(password, salt, iterations, 32, 'sha256');
}
function generateSalt32Byte() {
return crypto.randomBytes(32);
}
function generateFixedSalt32Byte() {
return Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex');
}
function bytesToHex(input) {
return input.toString('hex');
}
我正在尝试在 Nodejs 中复制此方法。我想知道它在 Node 中的等价物类似于
Java代码:
private final byte[] _createSaltedPassword(String password, byte[] salt, int iterationCount) {
byte[] dk;
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, 256);
SecretKeyFactory key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
dk = key.generateSecret(keySpec).getEncoded();
return dk;
}
为了这个示例,我保持用户 (user)、客户端随机数 (aabbccddaabbccdd)、密码 (Password123)、salt 和迭代计数 (4096) 相同。我最后一次尝试使用加密在 Node 中获得等效项。
const crypto = require("crypto");
const saltedPassword = crypto.pbkdf2Sync(password, salt, iterationCount, 32, 'sha256').toString('base64');
console.log('Salted Password:', saltedPassword);
用于摘要式身份验证。来自 Java 程序的输出日志:
Output log from Java program
Java 加盐密码: nA0hWFpZshs+iME/leUy+e2gM5mjIgo6PYJ8eNjRdhY=
节点加盐密码:PYgn6rcngiE0HSMwzmWhd2W5qTdaRilw4PEeuy3OyRo=
谢谢。
抱歉懒得查看链接代码,但我提供了两个示例 Java 和带有加密库的 NodeJS,它们使用 PBKDF2 算法从密码短语生成密钥。您可以 运行 在在线编译器中使用这两种代码 - Java code and NodeJs code.
这是带有 fixed = unsecure salt 的输出:
Generate a 32 byte long AES key with PBKDF2
aesKeySha256 length: 32 data: e1ea3e4b0376c0f9bf93b94fe71719a099317297b79108aacd88c8a355d7a3d4
安全警告:以下代码没有任何异常处理,仅供学习使用。不要使用 固定盐在生产中,它仅用于显示两个平台生成相同的密钥。
Java代码:
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("Generate a 32 byte long AES key with PBKDF2");
// get the password as char array
char[] passwordChar = "secret password".toCharArray();
final int PBKDF2_ITERATIONS = 15000; // number of iterations, higher is better but slower
// ### security warning - never use a fixed salt in production, this is for compare reasons only
byte[] salt = generateFixedSalt32Byte();
// please use below generateSalt32Byte()
//byte[] salt = generateSalt32Byte();
byte[] aesKeySha256 = generateAes256KeyPbkdf2Sha256(passwordChar, PBKDF2_ITERATIONS, salt);
System.out.println("aesKeySha256 length: " + aesKeySha256.length + " data: " + bytesToHex(aesKeySha256));
}
public static byte[] generateAes256KeyPbkdf2Sha256(char[] password, int iterations, byte[] salt) throws Exception {
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec keySpec = new PBEKeySpec(password, salt, iterations, 32 * 8);
return secretKeyFactory.generateSecret(keySpec).getEncoded();
}
private static byte[] generateSalt32Byte() {
SecureRandom secureRandom = new SecureRandom();
byte[] salt = new byte[32];
secureRandom.nextBytes(salt);
return salt;
}
private static byte[] generateFixedSalt32Byte() {
// ### security warning - never use this in production ###
byte[] salt = new byte[32]; // 32 x0's
return salt;
}
private static String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
return result.toString();
}
}
NodeJs 代码
console.log("Generate a 32 byte long AES key with PBKDF2");
var crypto = require('crypto');
var password = "secret password";
var PBKDF2_ITERATIONS = 15000; // number of iterations, higher is better but slower
// ### security warning - never use a fixed salt in production, this is for compare reasons only
var salt = generateFixedSalt32Byte();
// please use below generateSalt32Byte()
//var salt = generateSalt32Byte();
var aesKeySha256 = generateAes256KeyPbkdf2Sha256(password, PBKDF2_ITERATIONS, salt);
console.log('aesKeySha256 length: ',
aesKeySha256.length, ' data: ', bytesToHex(aesKeySha256));
function generateAes256KeyPbkdf2Sha256(password, iterations, salt) {
return crypto.pbkdf2Sync(password, salt, iterations, 32, 'sha256');
}
function generateSalt32Byte() {
return crypto.randomBytes(32);
}
function generateFixedSalt32Byte() {
return Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex');
}
function bytesToHex(input) {
return input.toString('hex');
}