【问题标题】:Java equivalent for PHP Triple DES ECB encryption/decryptionJava 等效于 PHP Triple DES ECB 加密/解密
【发布时间】:2015-09-13 09:06:41
【问题描述】:

我有一个下面的 PHP 函数,我想用 Java 实现但没有成功,我无法获得相同的输出:

function encryptText( $plainText, $key )
{
    $mcopen = mcrypt_module_open (MCRYPT_TripleDES, "", MCRYPT_MODE_ECB,"");
    $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size ($mcopen), MCRYPT_RAND);
    $td = mcrypt_module_open('tripledes', '', 'ecb', '');
    $cryptedHash = '';

    if (mcrypt_generic_init($td, $key, $iv) != -1)
    {
        $cryptedHash = mcrypt_generic($td, $plainText);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
    }
    return base64_encode($cryptedHash);
 }

这是我在here找到的java代码:

public static String encrypt(String message, String key) throws Exception {
    final MessageDigest md = MessageDigest.getInstance("md5");
    final byte[] digestOfPassword = md.digest(key.getBytes("utf-8"));
    final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    for (int j = 0, k = 16; j < 8;) {
        keyBytes[k++] = keyBytes[j++];
    }

    final SecretKey keyz = new SecretKeySpec(keyBytes, "DESede");
    final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, keyz, iv);

    final byte[] plainTextBytes = message.getBytes("utf-8");
    final byte[] cipherText = cipher.doFinal(plainTextBytes);
    final String encodedCipherText = new   sun.misc.BASE64Encoder().encode(cipherText);

    return encodedCipherText;
}

【问题讨论】:

    标签: java php encryption tripledes ecb


    【解决方案1】:

    你有几个问题。

    • 既然要使用ECB模式,那么就需要指定ECB模式。 CBC 是一种不同的模式。

    • 您没有在 PHP 代码中通过 MD5 运行您的密钥,因此您不应该在 Java 中这样做。

    • ECB 或 CBC 模式下的分组密码需要填充以加密任意消息。 Mcrypt 默认使用零填充,但您在 Java 中指定 PKCS#5 填充。由于默认的 Sun 提供程序没有实现 ZeroPadding,因此您需要自己通过指定“NoPadding”并自己实现零填充来实现它,或者使用 BouncyCastle 提供程序:Cipher.getInstance("DESede/ECB/ZeroPadding", "BC")


    其他注意事项:

    永远不要使用 ECB 模式。它在语义上不安全。如果您使用相同的密钥对同一消息进行两次加密,攻击者可以很容易地看到您再次加密了同一消息(或消息的同一部分)。

    【讨论】:

    • 感谢您的回答。我会尽力执行您的建议。对于 ECB 模式,我知道它不是很安全,但这实际上是在 php 端(合作伙伴)中实现的。
    【解决方案2】:

    解决了,解决办法:

    public static String cryptBC(String data, String key) throws Exception{
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        byte[] input = data.getBytes();
        byte[] keyBytes = key.getBytes() ;   
        SecretKeySpec skey = new SecretKeySpec(keyBytes, "DESede");
        Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding", "BC");
    
        if(input.length % 8 != 0){ 
            byte[] padded = new byte[input.length + 8 - (input.length % 8)];
            System.arraycopy(input, 0, padded, 0, input.length);
            input = padded;
        }
        System.out.println("input : " + new String(input));
        cipher.init(Cipher.ENCRYPT_MODE, skey);
        byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
        int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
        ctLength += cipher.doFinal(cipherText, ctLength);
    
        return new String(Base64.encodeBase64(cipherText));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多