我正在尝试加密java中的字符串,将其发送到我的node.js服务器,并对其进行解密。但是,当我尝试这样做时,我会在尝试解密时不断收到错误。
Java加密:
String privateKey = "someprivatekey";
String data = "dataToEncrypt";
DESKeySpec keySpec = new DESKeySpec(privateKey.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
byte[] dataToBytes = data.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
// send this string to server
String encryptedStr = Base64.encodeToString(cipher.doFinal(dataToBytes), 0);
node.js解密:
var privateKey = 'someprivatekey';
var decipher = crypto.createDecipher('des', privateKey);
var dec = decipher.update(textToDecipher, 'base64', 'utf8');
dec += decipher.final('utf8');
console.log('deciphered: ' + dec);
但是,我在decipher.final()行的node.js端遇到此错误:
TypeError: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
我已经尝试解码字符串并在节点端使用缓冲区,但它似乎也没有工作,我得到相同的错误解密错误。
var buffer = new Buffer(textToDecipher, 'base64');
var decipher = crypto.createDecipher('des', privateKey);
var dec = Buffer.concat([decipher.update(buffer), decipher.final()]);
任何想法我可能做错了什么?
答案 0 :(得分:5)
在节点服务器上创建解密对象时,您传递的是密码而不是实际密钥。为了指定实际密钥,您需要使用crypto.createDecipheriv()
,但这需要实际的IV
(此示例使用8个空字节,但不建议用于实际加密; Initialization Vector on wikipedia)
我能够通过显式指定填充,块模式和IV来实现您的示例:
String privateKey = "someprivatekey";
String data = "dataToEncrypt";
DESKeySpec keySpec = new DESKeySpec(privateKey.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
byte[] dataToBytes = data.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[8]));
// send this string to server
String encryptedStr = Base64.encodeToString(cipher.doFinal(dataToBytes), 0);
解密版本还明确指定了块模式(des-cbc),并正确地将密钥文本截断为前8个字节:
var privateKey = 'someprivatekey';
var textToDecipher = '9Y8GTNxhQkKSIm5pmH91VA=='; // Text "dataToEncrypt" encrypted using DES using CBC and PKCS5 padding with the key "someprivatekey"
var iv = new Buffer(8);
iv.fill(0);
var decipher = crypto.createDecipheriv('des-cbc', privateKey.substr(0,8), iv);
var dec = decipher.update(textToDecipher, 'base64', 'utf8');
dec += decipher.final('utf8');
console.log('deciphered: ' + dec);
答案 1 :(得分:1)
Java加密的DES默认模式是ECB,您需要在nodejs中指定:
var decipher = crypto.createDecipheriv('des-ecb', key, new Buffer(0))
var txt = decipher.update(encrypt_text, 'hex', 'utf8');
txt += decipher.final('utf8')
return txt