用PHP替换JAVA以实现PKCS5加密

我的任务是用运行PHP的东西替换遗留的java系统。

我正在用PHP代码取代Java加密技术。

cipherAlgorythm = "PBEWithMD5AndDES";                           
cipherTransformation = "PBEWithMD5AndDES/CBC/PKCS5Padding";     
PBEParameterSpec ps = new javax.crypto.spec.PBEParameterSpec(salt, iterations);
SecretKeyFactory kf = SecretKeyFactory.getInstance(cipherAlgorythm);
SecretKey key = kf.generateSecret(new javax.crypto.spec.PBEKeySpec(password.toCharArray()));
Cipher encryptCipher = Cipher.getInstance(cipherTransformation);   
encryptCipher.init(Cipher.ENCRYPT_MODE, key, ps);
byte[] output = encryptCipher.doFinal("This is a test string".getBytes("UTF-8"));

似乎是Java的胆量

在PHP中,我正在做

$hashed_key = pbkdf2('md5', $this->key, $this->salt, $this->reps , <GUESS 1>, TRUE);
$output = mcrypt_encrypt(MCRYPT_DES, $hashed_key, "This is a test string", MCRYPT_MODE_CBC, <GUESS 2>);

pbkdf2来自这里。

所以<GUESS 1>是关键尺寸, <GUESS 2>是IV。 我玩过这些都无济于事。 有没有人有这样的价值观的建议? 据我所见,加密本身应该是可移植的,但我不确定某些Java方法正在发生什么。

它看起来像java创建一个IV的地方,但我不明白如何或在哪里。

有关

解密(使用PHP)Java加密(PBEWithMD5AndDES)


你可能想看看http://us3.php.net/manual/en/ref.mcrypt.php#69782,但基本上他实现了一个DIY填充解决方案:

function pkcs5_pad ($text, $blocksize) 
{ 
    $pad = $blocksize - (strlen($text) % $blocksize); 
    return $text . str_repeat(chr($pad), $pad); 
} 

这可能是你最好的选择,但如果你看看这个评论,他关于如何验证每个步骤是正确的建议可能对你有用。

https://stackoverflow.com/a/10201034/67566

理想情况下,你应该离开DES,因为这个填充将成为PHP中的一个问题,为什么不看看你是否可以将加密算法改变为更麻烦更安全的方法?

为了帮助您显示此页面:http://www.ietf.org/rfc/rfc4772.txt,其中简洁地表示DES易受暴力攻击,因此已被弃用并被AES取代。


两个现有的答案都有帮助,但我会在这里发布完整的解决方案。

我没有看到它在任何地方都有记录,但在查看这个加密方案的实现之后,我发现密钥是加密散列的前8个字节,而IV是最后8个字节。

 public function get_key_and_iv($key, $salt, $reps) {
    $hash = $key . $salt;
    for ($i = 0; $i< $reps; $i++) {
      $hash = md5($hash, TRUE);
    }
    return str_split($hash,8);
  }

似乎有窍门。 在我的问题中替换pbkdf2,否定了<GUESS 1>的需要,并给出了<GUESS 2>的值

然后我被詹姆斯布莱克提到并设法解决的填充问题所困扰。 所以最终的代码是

list($hashed_key, $iv) = get_key_and_iv($key, $salt, $reps);
// 8 is DES block size.
$pad = 8 - (strlen($plaintext) % 8);
$padded_string = $plaintext . str_repeat(chr($pad), $pad);
return mcrypt_encrypt(MCRYPT_DES, $hashed_key, $padded_string, MCRYPT_MODE_CBC, $iv);

您也可以使用hash_pbkdf2 PHP(5.5)函数,而不是使用PBKDF2 PHP库。

根据PHP文档,GUESS 1是创建派生密钥的长度

长度

输出字符串的长度。 如果raw_output为TRUE,则这对应于派生密钥的字节长度,如果raw_output为FALSE,则这对应于派生密钥的字节长度的两倍(因为密钥的每个字节都以两个hexits的形式返回)。

如果通过0,则使用所提供的算法的整个输出。

也许这篇文章(什么是最佳的哈希大小以字节为单位?)对你来说很有意思。

GUESS 2或IV是一个随机初始化向量,用于创建独特的盐以生成散列。

您可以使用mycript_create_iv函数创建IV。

看看PHP.net中的完整示例

<?php
$password = "password";
$iterations = 1000;

// Generate a random IV using mcrypt_create_iv(),
// openssl_random_pseudo_bytes() or another suitable source of randomness
$salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);

$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 20);
echo $hash;
?>
链接地址: http://www.djcxy.com/p/17899.html

上一篇: Replacing JAVA with PHP for PKCS5 encryption

下一篇: Common Gotchas