javascript - 将 Java 的 PBEWithMD5AndDES 转换为 JavaScript

标签 javascript java encryption passwords cryptojs

我正在尝试在 JavaScript 中复制 Java 代码。 下面是我的Java代码:

public static String encrypt(String input)
final byte[] SALT= { (byte) 0x21, (byte) 0x21, (byte) 0xF0, (byte) 0x55, (byte) 0xC3, (byte) 0x9F, (byte) 0x5A, (byte) 0x75                     };
final int   ITERATION_COUNT = 31;
{
    if (input == null)
    {
        throw new IllegalArgumentException();
    }
    try
    {

        KeySpec keySpec = new PBEKeySpec(null, SALT, ITERATION_COUNT);
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(SALT, ITERATION_COUNT);

        SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);

        Cipher ecipher = Cipher.getInstance(key.getAlgorithm());
        ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);

        byte[] enc = ecipher.doFinal(input.getBytes());

        String res = new String(Base64.encodeBase64(enc));
        // escapes for url
        res = res.replace('+', '-').replace('/', '_').replace("%", "%25").replace("\n", "%0A");
        LOGGER.info("String Encrypted Successfully");
        return res;

    }
    catch (Exception e)
    {
        LOGGER.error("encrypt Exception: "+e.getMessage());
    }


    return "";

}

到目前为止,JavaScript 代码如下:

var encrypt = function(){
    var iterations = 31;
    var key = CryptoJS.MD5("PBEWithMD5AndDES");
    var salt = CryptoJS.enc.Hex.parse('0021002100f0005500C3009F005A0075'); 
    var options = {
        mode: CryptoJS.mode.CBC, 
        iv: salt
    };
    var hashedPassword = CryptoJS.MD5($scope.data.webPassword);
    var encryptedPassword = CryptoJS.DES.encrypt(hashedPassword, key,options).toString();
    var result = encryptedPassword.toString(CryptoJS.enc.Base64);
}

但是通过这两种加密,我得到的编码字符串是不同的。

最佳答案

PBEwithMD5andDES 是过时的技术,现在不应使用。此答案仅用于演示目的。

PBEwithMD5andDES 定义于 PKCS#5 v1.5无非是使用PBKDF1(带有MD5)导出 key +IV并使用DES加密。

var password = CryptoJS.enc.Utf8.parse("test");
var salt = CryptoJS.enc.Hex.parse("2121F055C39F5A75");
var iterations = 31;

// PBE according to PKCS#5 v1.5 (in other words: PBKDF1)
var md5 = CryptoJS.algo.MD5.create();
md5.update(password);
md5.update(salt);
var result = md5.finalize();
md5.reset();
for(var i = 1; i < iterations; i++) {
    md5.update(result);
    result = md5.finalize();
    md5.reset();
}

// splitting key and IV
var key = CryptoJS.lib.WordArray.create(result.words.slice(0, 2));
var iv = CryptoJS.lib.WordArray.create(result.words.slice(2, 4));

var encrypted = CryptoJS.DES.encrypt("test", key, {
    iv: iv
});

enchex.innerHTML = encrypted.ciphertext.toString();
encbase64.innerHTML = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/tripledes.js"></script>
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/md5.js"></script>
<div>Hex: <span id="enchex"></span></div>
<div>Base64: <span id="encbase64"></span></div>

Here is a jsFiddle进行实验,这里是 example Java code 。两者产生相同的十六进制结果:aa8101a7d63093c6。

<小时/>

安全考虑:

不应使用 PBEwithMD5andDES,并且有更好的替代方案,例如 PBEWithHmacSHA256AndAES_128,它们需要稍微不同的方法。

迭代次数必须很大(一千到一百万次),以便难以暴力破解密码。 DES 仅提供 56 位安全性,因此甚至可以使用当今的手段直接暴力破解 key 。

盐必须随机生成才能实现语义安全。盐本身不需要保密。由于它的长度已知,因此可以简单地将其添加到密文之前并在解密之前将其切掉。

关于javascript - 将 Java 的 PBEWithMD5AndDES 转换为 JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38990630/

相关文章:

javascript - 播放音乐

php - 在 jQuery 函数中使用 smarty 变量

java - 格式 XMLGregorianCalendar

java.lang.NoSuchMethodError : org. apache.xml.security.transforms.Transform.init()V

html - TripAdvisor 上可能加密的 "a href"链接

php - 每个 Web 开发人员都应该了解加密的哪些内容?

Python 3.6 异或文件解密

javascript - asp.net 数据输入静态网格

javascript - 将数组添加到查询中的所有节点 - Firebase JS

java - 如何从迭代器 next() 方法返回的对象中获取信息?