加密/解密-将PHP编码/解码为JAVA


Encrypt / Decrypt - Encode / Decode PHP Equvilent to JAVA

有人能解释一下PHP代码并告诉我如何用Java移植代码吗?

以下是PHP代码:

function decode_string($encoded_string, $key) {
    $decoded = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encoded_string), MCRYPT_MODE_CBC, md5(md5($key))), "'0");
    return $decoded;
}

好吧,我会咬一口,但我会让你做编码:

  • rtrim(x, "'0"):删除PHP使用的无脑零填充(0..15字节的零),这使明文成为CBC所需的块大小的X倍。你必须自己编程,因为Bouncy Castle中没有它,所以不要使用任何填充模式。只需移除解密明文右侧的零值字节即可
  • mcrypt_decrypt(MCRYPT_RIJNDAEL_256):可能有人认为这意味着AES-256,但事实并非如此。它是Rijndael,块大小为256位。您需要Java中的Bouncy Castle库来解密密码的非标准化部分
  • MD5($key)有人需要256位的密钥材料,并认为MD5值对密码的十六进制编码就足够了。事实并非如此,因为它只提供了一半的熵(每个字节2个十六进制字符)。再加上MD5不是一个密码哈希函数,这充其量是虚伪的
  • base64_decode($encoded_string):好吧,期待base64编码,如果密文需要以ASCII兼容文本的形式出现,这是可以的
  • MCRYPT_MODE_CBC:没关系,但由于PHP主要用作web语言,我预计该消息容易受到填充预言机/纯文本预言机的攻击,当然,您应该预计密文的任何更改都是无法检测到的
  • md5(md5($key)):两次应用MD5并不能使其比零IV更安全,并且不要忘记这些函数中的每一个执行的十六进制转换;幸运的是,这意味着IV至少是256位,而不是128位

所以你需要使用:

new BufferedBlockCipher(new RijndaelEngine(256))

在Bouncy Castle的轻量级API中。

快乐的编码,你擅长Java,所以这应该是轻而易举的事。尽快升级,远离这些垃圾。