Nodejs和java密钥的生成
Nodejs和java密钥的生成
Java代码:
public String encryption(String str)throws Exception{
try {
String KEY = "123456789";
byte[] enCriptSHA1String = enCriptSHA1(str);//SHA-1
String base64String = enBase64(enCriptSHA1String);//
System.out.println("1 "+base64String);
System.out.println("1.5 "+(str + "_" + base64String));
byte[] enCrptString = enCrpt((str + "_" + base64String).getBytes(), KEY.getBytes());//DESede
String base64StringRe = enBase64(enCrptString);
System.out.println("2 "+base64StringRe);
str=URLEncoder.encode(base64StringRe);
System.out.println("3 "+str);
} catch (Exception e) {
throw e;
}
return str;
}
public byte[] enCriptSHA1(String authenticator){
//加密的方式
final String Algorithm = "SHA-1";
//实例MessageDigest对象
MessageDigest md=null;
byte[] encode=null;
//加密数据转换成字节
byte[] bt=authenticator.getBytes();
try {
//SHA-1加密
md=MessageDigest.getInstance(Algorithm);
md.update(bt);
//二行制到字符串的转变
encode=md.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return encode;
}
public byte[] enCrpt(byte[] reqStr ,byte[] enkey){
//加密的方式
final String Algorithm = "DESede";
//加密后的数据
byte[] encoded = null;
//根据密钥加密对象
Cipher cipher = null;
//得到密钥
SecretKey secretKey = null;
try {
//得到密钥
secretKey = getSecretKey(enkey,Algorithm);
//加密
cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
//得到解加密后的数据
encoded = cipher.doFinal(reqStr);
} catch (Exception e) {
}
return encoded;
}
nodejs 代码:
function aesEncrypt(data) {
var cipher = crypto.createHash('sha1');
var encodeC = cipher.update(data).digest().toString('base64');
var ciphertwo = crypto.createCipher('des-ede',new Buffer('12345678'),0);
var endate = data+'_'+encodeC;
var en = ciphertwo.update(new Buffer(endate),'binary','base64')+ciphertwo.final('base64');
console.info("en: "+en+" ");
return en;
};
以上分别是我java和nodejs加密写法,为什么得出的结果不一样呢请大神指导下,看看哪里有错。
好的,我们可以对比并分析你的Java和Node.js代码,找出可能的原因,并提供改进后的代码。
Java 代码
public String encryption(String str) throws Exception {
try {
String KEY = "123456789";
byte[] enCriptSHA1String = enCriptSHA1(str); // SHA-1
String base64String = new String(Base64.getEncoder().encode(enCriptSHA1String), StandardCharsets.UTF_8);
System.out.println("1 " + base64String);
System.out.println("1.5 " + (str + "_" + base64String));
byte[] enCrptString = enCrpt((str + "_" + base64String).getBytes(), KEY.getBytes()); // DESede
String base64StringRe = new String(Base64.getEncoder().encode(enCrptString), StandardCharsets.UTF_8);
System.out.println("2 " + base64StringRe);
str = URLEncoder.encode(base64StringRe, StandardCharsets.UTF_8.name());
System.out.println("3 " + str);
} catch (Exception e) {
throw e;
}
return str;
}
public byte[] enCriptSHA1(String authenticator) {
final String Algorithm = "SHA-1";
MessageDigest md = null;
byte[] encode = null;
byte[] bt = authenticator.getBytes();
try {
md = MessageDigest.getInstance(Algorithm);
md.update(bt);
encode = md.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return encode;
}
public byte[] enCrpt(byte[] reqStr, byte[] enkey) {
final String Algorithm = "DESede";
byte[] encoded = null;
Cipher cipher = null;
SecretKey secretKey = null;
try {
secretKey = new SecretKeySpec(enkey, Algorithm);
cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
encoded = cipher.doFinal(reqStr);
} catch (Exception e) {
e.printStackTrace();
}
return encoded;
}
Node.js 代码
const crypto = require('crypto');
function aesEncrypt(data) {
const sha1 = crypto.createHash('sha1');
const encodeC = sha1.update(data).digest().toString('base64');
const desCipher = crypto.createCipher('des-ede', '12345678');
const endate = data + '_' + encodeC;
let en = desCipher.update(endate, 'utf8', 'base64') + desCipher.final('base64');
console.info("en: " + en);
return en;
}
分析与改进
-
SHA-1 加密:
- 在Java中,
enCriptSHA1
方法直接返回了字节数组。 - 在Node.js中,使用
toString('base64')
将字节数组转换为Base64字符串。确保在Java中也进行相同的转换。
- 在Java中,
-
DESede 加密:
- Java中的
enCrpt
方法使用的是DESede
算法。 - Node.js中的
createCipher
方法也需要指定相同的算法。但是,Node.js的crypto
库默认使用des-ede3
,而不是des-ede
。如果需要des-ede
,可以考虑使用createCipheriv
并手动设置参数。
- Java中的
改进后的Node.js 代码
const crypto = require('crypto');
function aesEncrypt(data) {
const sha1 = crypto.createHash('sha1');
const encodeC = sha1.update(data).digest().toString('base64');
const desCipher = crypto.createCipheriv('des-ede3', Buffer.from('12345678'), ''); // 使用 'des-ede3' 和密钥
const endate = data + '_' + encodeC;
let en = desCipher.update(endate, 'utf8', 'base64') + desCipher.final('base64');
console.info("en: " + en);
return en;
}
通过上述改进,你可以确保Java和Node.js代码在处理SHA-1和DESede加密时的一致性。希望这能帮助你解决问题!
谢谢,这个我看过,好像不行。。。
你的 getSecretKey 方法在哪里? 贴了个小片段,想试验一下都不行。。。。
我也在这里卡了一段时间,后来各种尝试终于解决了:(不太懂这个网站应该怎么格式代码,代码贴的比较丑,见谅了;)
AESCrypt.js
var crypto = require('crypto');
var AESCrypt = {};
AESCrypt.decrypt = function(cryptkey, iv, encryptdata) {
encryptdata = new Buffer(encryptdata, ‘base64’).toString(‘binary’);
var decipher = crypto.createDecipheriv(‘aes-128-cbc’, cryptkey, iv);
var decoded = decipher.update(encryptdata, ‘binary’, ‘utf8’);
decoded += decipher.final('utf8');
return decoded;
}
AESCrypt.encrypt = function(cryptkey, iv, cleardata) {
var encipher = crypto.createCipheriv(‘aes-128-cbc’, cryptkey, iv);
var encryptdata = encipher.update(cleardata, ‘utf8’, ‘binary’);
encryptdata += encipher.final(‘binary’);
var encode_encryptdata = new Buffer(encryptdata, ‘binary’).toString(‘base64’);
return encode_encryptdata;
}
module.exports = AESCrypt;
AESCryptTest.js
var AESCrypt = require('./AESCrypt');
var cryptkey = new Buffer('1234567890123456','utf-8'),
iv = new Buffer('00000000000000000000000000000000','hex').toString('utf-8');
var obj = {
a:'1',
b:'2'
}
var objStr = JSON.stringify(obj);
var encStr = AESCrypt.encrypt(cryptkey, iv, objStr);
var decStr = AESCrypt.decrypt(cryptkey, iv, encStr);
var decObj = JSON.parse(decStr);
console.log(decObj);
在你的问题中,Java 和 Node.js 的加密实现存在一些差异,导致最终结果不同。以下是针对你提供的代码进行的修改,以确保两者能够一致地执行加密操作。
Java 代码
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;
public String encryption(String str) throws Exception {
try {
String KEY = "123456789";
byte[] enCriptSHA1String = enCriptSHA1(str); // SHA-1
String base64String = Base64.getEncoder().encodeToString(enCriptSHA1String); // base64 encode
System.out.println("1 " + base64String);
System.out.println("1.5 " + (str + "_" + base64String));
byte[] enCrptString = enCrpt((str + "_" + base64String).getBytes(), KEY.getBytes()); // DESede
String base64StringRe = Base64.getEncoder().encodeToString(enCrptString);
System.out.println("2 " + base64StringRe);
str = URLEncoder.encode(base64StringRe, "UTF-8");
System.out.println("3 " + str);
} catch (Exception e) {
throw e;
}
return str;
}
public byte[] enCriptSHA1(String authenticator) {
final String Algorithm = "SHA-1";
MessageDigest md = null;
byte[] encode = null;
byte[] bt = authenticator.getBytes();
try {
md = MessageDigest.getInstance(Algorithm);
md.update(bt);
encode = md.digest();
} catch (Exception e) {
e.printStackTrace();
}
return encode;
}
public byte[] enCrpt(byte[] reqStr, byte[] enkey) {
final String Algorithm = "DESede/ECB/PKCS5Padding";
byte[] encoded = null;
Cipher cipher = null;
SecretKeySpec secretKey = new SecretKeySpec(enkey, Algorithm);
try {
cipher = Cipher.getInstance(Algorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
encoded = cipher.doFinal(reqStr);
} catch (Exception e) {
e.printStackTrace();
}
return encoded;
}
Node.js 代码
const crypto = require('crypto');
function aesEncrypt(data) {
const hash = crypto.createHash('sha1').update(data).digest();
const base64Sha1 = hash.toString('base64');
const key = crypto.scryptSync('12345678', '', 24); // Generate 24-byte key for 3DES
const cipher = crypto.createCipheriv('des-ede3', key, '');
let encrypted = cipher.update(data + '_' + base64Sha1, 'utf8', 'base64') + cipher.final('base64');
console.info("en: " + encrypted);
return encrypted;
}
// Test the function
aesEncrypt('test'); // Replace 'test' with your input string
主要修改点
-
Java:
- 使用
Base64.getEncoder().encodeToString
进行 Base64 编码。 - 确保
enCrpt
方法使用正确的 DESede 加密模式(如DESede/ECB/PKCS5Padding
)。
- 使用
-
Node.js:
- 使用
crypto.scryptSync
生成 24 字节的密钥,适合des-ede3
加密算法。 - 使用
createCipheriv
方法进行初始化向量(IV)设置,尽管这里的 IV 是空的,但这是标准做法。
- 使用
通过这些修改,可以确保 Java 和 Node.js 的加密结果一致。