Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我总是在nodejs本机密码中出错?_Javascript_Node.js_Encryption_Des - Fatal编程技术网

Javascript 为什么我总是在nodejs本机密码中出错?

Javascript 为什么我总是在nodejs本机密码中出错?,javascript,node.js,encryption,des,Javascript,Node.js,Encryption,Des,这是我的密码: const crypto = require('crypto') let enterJS = 'h'; let enterStr = null; enterStr = encrypt(enterJS, 'des-ecb').toUpperCase(); console.log("===============>>>> ENTER STR : " + enterStr); function encrypt(plaintext, algor

这是我的密码:

const crypto = require('crypto')
let enterJS = 'h';
let enterStr = null;
enterStr = encrypt(enterJS, 'des-ecb').toUpperCase();
console.log("===============>>>> ENTER STR : " + enterStr);
function encrypt(plaintext, algorithm) {
    var keyStr = "imtestKey";
    var key = new Buffer(keyStr);
    var cipher = crypto.createCipher(algorithm, key);
    cipher.setAutoPadding(true);
    var ciph = cipher.update(plaintext, 'ascii');
    var ciphf = cipher.final();
    return ciph.toString('hex') + ciphf.toString('hex');
}
但我得到的结果是:

=============>>>>输入STR:16CE7F2DEB9BB56D

我在这个网站上测试的正确结果是:

des模式:欧洲央行

填充模式:pkcs7padding

密码:imtestKey

输出:十六进制

正确的结果(与我的java代码相同)是

832e52ebd3fb9059

我的节点版本是v8.9.0,如何获得正确的结果

这是我的java代码:

import java.lang.StringBuilder;
import javax.crypto.Cipher;
import java.security.SecureRandom;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;

public class Test {
    public static void main(String[] args) {
        String js = "h";
        try {
            byte[] bs = encrypt(js.getBytes(), "imtestKey".getBytes());
            System.out.println(byte2hex(bs));
        } catch(Exception ex) {

        }
    }

    public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
        SecureRandom sr = new SecureRandom();
        DESKeySpec dks = new DESKeySpec(key);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
        return cipher.doFinal(src);
    }


    public static String byte2hex(byte[] b) {
        StringBuilder sb = new StringBuilder();
        String stmp = "";

        for(int n = 0; b != null && n < b.length; ++n) {
            stmp = Integer.toHexString(b[n] & 255);
            if (stmp.length() == 1) {
                sb.append("0").append(stmp);
            } else {
                sb.append(stmp);
            }
        }

        return sb.toString().toUpperCase();
    }
}
导入java.lang.StringBuilder;
导入javax.crypto.Cipher;
导入java.security.SecureRandom;
导入javax.crypto.spec.DESKeySpec;
导入javax.crypto.SecretKeyFactory;
导入javax.crypto.SecretKey;
公开课考试{
公共静态void main(字符串[]args){
字符串js=“h”;
试一试{
byte[]bs=encrypt(js.getBytes(),“imtestKey.getBytes());
系统输出println(字节2hex(bs));
}捕获(例外情况除外){
}
}
公共静态字节[]加密(字节[]src,字节[]密钥)引发异常{
SecureRandom sr=新的SecureRandom();
DESKeySpec dks=新的DESKeySpec(键);
SecretKeyFactory keyFactory=SecretKeyFactory.getInstance(“DES”);
SecretKey securekey=keyFactory.generateSecret(dks);
Cipher Cipher=Cipher.getInstance(“DES”);
cipher.init(cipher.ENCRYPT_模式,securekey,sr);
返回cipher.doFinal(src);
}
公共静态字符串字节2hex(字节[]b){
StringBuilder sb=新的StringBuilder();
字符串stmp=“”;
对于(int n=0;b!=null&&n
除了安全方面(如前所述,DES和ECB以及无密钥派生都是不安全的),您正在使用一个不推荐使用的函数,该函数从提供的密码派生密钥

crypto.createCipher()
的实现使用OpenSSL函数
EVP_BytesToKey
导出
密钥,摘要算法设置为MD5,一次迭代,无盐。缺少salt允许字典攻击,因为相同的密码总是创建相同的密钥。低迭代次数和非加密安全哈希算法允许非常快速地测试密码

改为使用,它按原样使用提供的密钥:

const crypto = require('crypto')
let enterJS = 'h';
let enterStr = null;
function encrypt(plaintext, algorithm) {
    var keyStr = "imtestKey";
    var key = Buffer.alloc(8, keyStr);
    var cipher = crypto.createCipheriv(algorithm, key, Buffer.alloc(0));
    cipher.setAutoPadding(true);
    var ciph = cipher.update(Buffer.from(plaintext));
    var ciphf = cipher.final();
    return Buffer.concat([ciph, ciphf]).toString('hex');
}
enterStr = encrypt(enterJS, 'des-ecb').toUpperCase();
console.log("===============>>>> ENTER STR : " + enterStr);
createCipheriv
API将拒绝9字节长的密钥,因为DES需要8字节的密钥。我做了一个变通办法,从提供的密码中取出前8个字节作为密钥,现在它正在打印您想要的结果

输出:

================>>>>输入STR:832E52EBD3FB9059

密钥“imtestKey”的长度不正确,DES需要一个长度为8字节的密钥,而提供的密钥为9字节。还请注意,每个字节的LSB都被忽略。@zaph但是为什么我使用java、web工具和crypto js库,那么我就可以得到正确的答案了result@rustyx请参阅下面的java代码。如果密钥长度不正确,则加密未定义。使用正确的密钥长度,DES为8字节。@zaph如果您说密钥不正确,为什么我可以用web工具和java代码得到正确的答案?