【问题标题】:Require similler java code for php encryption scriptphp加密脚本需要similler java代码
【发布时间】:2016-02-14 21:47:48
【问题描述】:

我有一个 PHP 加密功能。我需要一个java计数器部分。由于我对PHP的了解有限,我无法理解。有人懂这两种语言,请帮忙。

PHP 代码:

function encrypt($decrypted, $keyvalue) {
    // Build a 256-bit $key which is a SHA256 hash of $keyvalue.
    $key = hash('SHA256', $keyvalue, true);
    // Build $iv and $iv_base64.  We use a block size of 128 bits (AES compliant) and CBC mode.  (Note: ECB mode is inadequate as IV is not used.)
    srand(); $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
    if (strlen($iv_base64 = rtrim(base64_encode($iv), '=')) != 22) return false;
    // Encrypt $decrypted and an MD5 of $decrypted using $key.  MD5 is fine to use here because it's just to verify successful decryption.
    $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $decrypted . md5($decrypted), MCRYPT_MODE_CBC, $iv));
    // We're done!
    return $iv_base64 . $encrypted;
}

提前致谢 阿尼鲁达

【问题讨论】:

  • 显然每行代码都有cmets!所以你应该能够用java编写代码,例如:对于第一行评论,你可以从stackoverflow.com/questions/5531455/…开始
  • 这段代码中存在一些严重的密钥派生和 MAC 漏洞。我建议使用久经考验的库,而不是使用自己的密码学或从互联网上复制粘贴代码。
  • 感谢您的回复。我不知道的东西很少,比如 MCRYPT_RIJNDAEL_128MCRYPT_MODE_CBC。这就是我问的原因。我尝试使用 JavaBridge.jar 从 java 执行 PHP 脚本。但这也需要 PHP 在机器上。所以我有点卡住了。

标签: java php encryption


【解决方案1】:

应该这样做。

public static byte[] encrypt(byte[] decrypted, byte[] keyvalue) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{
    MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
    byte[] key = sha256.digest(keyvalue);

    MessageDigest md5 = MessageDigest.getInstance("MD5");
    byte[] checksum = md5.digest(decrypted);

    //The length of the value to encrypt must be a multiple of 16.
    byte[] decryptedAndChecksum = new byte[(decrypted.length + md5.getDigestLength() + 15) / 16 * 16];
    System.arraycopy(decrypted, 0, decryptedAndChecksum, 0, decrypted.length);
    System.arraycopy(checksum, 0, decryptedAndChecksum, decrypted.length, checksum.length);
    //The remaining bytes of decryptedAndChecksum stay as 0 (default byte value) because PHP pads with 0's.

    SecureRandom rnd = new SecureRandom();
    byte[] iv = new byte[16];
    rnd.nextBytes(iv);
    IvParameterSpec ivSpec = new IvParameterSpec(iv);

    Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), ivSpec);
    byte[] encrypted = Base64.encodeBase64(cipher.doFinal(decryptedAndChecksum));

    byte[] ivBase64 = Base64.encodeBase64String(iv).substring(0, 22).getBytes();
    byte[] output = new byte[encrypted.length + ivBase64.length];
    System.arraycopy(ivBase64, 0, output, 0, ivBase64.length);
    System.arraycopy(encrypted, 0, output, ivBase64.length, encrypted.length);
    return output;
}

MCRYPT_RIJNDAEL_128 和 MCRYPT_MODE_CBC 在 java 中的等价物是 AES/CBC/NoPadding。您还需要一个用于 Base64 编码的实用程序,上面的代码使用 Apache Codec 库中的Base64

此外,由于加密密钥是 256 位,您需要 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。这些可以从 Oracle 的网站下载。

最后,请注意 ntoskrnl 的警告。这种加密真的可以更好,不要从PHP手册中复制粘贴。

【讨论】:

  • 仅供参考:策略文件仅适用于 Oracle JRE – OpenJDK,它是大多数 GNU/Linux 系统的默认设置,不会限制加密的强度。
  • 非常感谢大家。
猜你喜欢
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
相关资源
最近更新 更多