将Java的PBEWithMD5AndDES转换为JavaScript [英] Converting Java's PBEWithMD5AndDES to JavaScript

查看:1121
本文介绍了将Java的PBEWithMD5AndDES转换为JavaScript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用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);

密码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(\\\
,%0A);
LOGGER.info(String Encrypted Successfully);
return res;

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


返回;

}

和JavaScript代码,到目前为止,

  var encrypt = function(){
var iterations =
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);
}

但是加密后,我得到的编码字符串是不同的。 / p>

解决方案

PBEwithMD5andDES是过时的技术,现在不应该使用。用于演示的目的。



PBEwithMD5andDES在 PKCS#5 v1.5 ,这只是使用PBKDF1(使用MD5)派生密钥+ IV并使用DES进行加密。



  var password = CryptoJS.enc.Utf8.parse(test) ; var salt = CryptoJS.enc.Hex.parse(2121F055C39F5A75); var iterations = 31; //根据PKCS#5 v1.5的PBE(换句话说:PBKDF1)var md5 = CryptoJS.algo.MD5.create (); md5.update(salt); var result = md5.finalize(); md5.reset(); for(var i = 1; i< iterations; i ++){md5.update (结果); result = md5.finalize(); md5.reset();} // split key and IVvar 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);  

  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>  

/ div>



这是一个jsFiddle 实验,这里是示例Java代码。两者都在Hex中产生相同的结果:aa8101a7d63093c6。






安全注意事项:



不能使用PBE与M5和DES,而且有更好的选择,比如PBEWithHmacSHA256AndAES_128,它们需要稍微不同的方法。



迭代次数必须很大百万),以使它很难强制密码。 DES只提供56位的安全性,所以甚至可以用今天的方法直接强制键。



盐必须随机生成才能实现语义安全。盐本身不需要秘密。由于它有一个已知的长度,它可以简单地在密文之前加密并在解密之前被切掉。


I'm trying to replicate the Java code in JavaScript. below is my Java code:

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 "";

}

and the JavaScript code, so far hammed up is below:

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);
}

but with both the encryption the encoded string I'm getting is different.

解决方案

PBEwithMD5andDES is obsolete technology and should not be used nowadays. This answer is only provided for demonstration purposes.

PBEwithMD5andDES is defined in PKCS#5 v1.5 which is nothing more than deriving key+IV using PBKDF1 (with MD5) and encrypting with 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 to experiment with and here is the example Java code. Both produce the same result in Hex: aa8101a7d63093c6.


Security considerations:

PBEwithMD5andDES should not be used and there are better alternatives like PBEWithHmacSHA256AndAES_128 which require a slightly different approach.

The number of iterations must be large (a thousand to a million) in order to make it hard to brute-force the password. DES only provides 56 bits of security, so it is even possible to brute-force the key directly with today's means.

The salt must be randomly generated in order to achieve semantic security. The salt itself doesn't need to be secret. Since it has a known length it can be simply prepended to the ciphertext and sliced off before decryption.

这篇关于将Java的PBEWithMD5AndDES转换为JavaScript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆