【问题标题】:Java/PHP Encryption CAST-256Java/PHP 加密 CAST-256
【发布时间】:2015-09-21 12:51:21
【问题描述】:

我有这个 PHP 中的旧代码,我想用 Java 重现:

function enCrypt($data = null) {
    $key = 'thisismysupersecretkeyglhf1';

    $encoded=mcrypt_encrypt(MCRYPT_CAST_256,
    $key,
    $data,
    MCRYPT_MODE_ECB
    );

    $encoded = base64_encode($encoded);

    return $encoded;
}

function deCrypt($data = null) {
    $key = 'thisismysupersecretkeyglhf1';

    $decrypted= mcrypt_decrypt(
    MCRYPT_CAST_256,
    $key,
    base64_decode($data),
    MCRYPT_MODE_ECB
    );

    return $decrypted;
}

我正在通过以下方式使用 Bouncy Castle CAST-6 引擎:

public static final String KEY = "thisismysupersecretkeyglhf1";


public static String encrypt(String toDecrypt) throws NoSuchPaddingException,
        NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException,
        InvalidKeyException, BadPaddingException, IllegalBlockSizeException, DecoderException, UnsupportedEncodingException {

    Cipher cipher = Cipher.getInstance("CAST6/ECB/NoPadding");

    SecretKeySpec key=new SecretKeySpec(KEY.getBytes(),"CAST6");

    cipher.init(Cipher.ENCRYPT_MODE, key);

    String decoded=org.apache.commons.codec.binary.Base64.encodeBase64String(cipher.doFinal(toDecrypt.getBytes()));

    return decoded;
}

public static String decrypt(String toDecrypt) throws NoSuchPaddingException,
        NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException,
        InvalidKeyException, BadPaddingException, IllegalBlockSizeException, DecoderException, UnsupportedEncodingException {

    Cipher cipher = Cipher.getInstance("CAST6/ECB/NoPadding");

    SecretKeySpec key=new SecretKeySpec(KEY.getBytes(),"CAST6");

    cipher.init(Cipher.DECRYPT_MODE, key);

    byte[] decoded=org.apache.commons.codec.binary.Base64.decodeBase64(toDecrypt);

    return new String(cipher.doFinal(decoded));
}

但是,我无法生成相同的加密结果或解密使用 JAVA 在 PHP 中加密的任何内容。

我缺少什么?

这是一个填充问题吗?通读 mcrypt 文档,他们似乎对密钥和数据进行了大量填充。我的密钥(旧密钥)长 27 个字符,我认为 mcrypt 应该将其填充到 32 个字节,因为 mcrypt_get_key_size(MCRYPT_CAST_256,MCRYPT_MODE_ECB) 结果为 32。

有关更多信息,我要加密的字符串是“1111111111111111”。我不知道这是否会被 PHP 填充,但我认为不会,因为 mcrypt_get_block_size(MCRYPT_CAST_256,MCRYPT_MODE_ECB) 返回 16,这正是我使用的长度。

我对密码学非常缺乏经验,所以我有点迷茫。也许如果我可以调试 mcrypt 内部,我可以更好地了解正在发生的事情。

如果能在 Java 中实现这些功能,我们将不胜感激。

PD。我知道这个算法不是最好的,不使用 IV 以及使用 ECB 在某种程度上令人担忧,但这仅适用于遗留代码集成。

【问题讨论】:

  • 我在使用 PHP Delphi 和 AES-256 时遇到了同样的问题。这也是一些填充问题,因此我们在 Web 服务的两端都进行了前缀处理,以便获得相同的前缀。更擅长对称密码学的人将能够为您提供更多帮助。祝你好运!
  • 能否也发布一个 PHP 密文(十六进制)?

标签: java php encryption cryptography mcrypt


【解决方案1】:

所以我终于想通了。

显然,Cast6 算法的 PHP 实现似乎不是标准的。

起初,我什至无法为算法重现与 test vectors 中的值相同的值,因此我精神崩溃了。所以是时候看看PHP的源码了。

我下载了 Ryan Gilfether 的 PhpCrypt Library,它产生的结果与 php 的 mcrypt 库完全相同。并开始调试。

我注意到 php 的实现,在将 key 和 data 分成 4 个字节的块后,它反转了这些块的内容。这在 Masking 和 Round Keys 的生成中尤为重要,因为它们因此发生了很大的变化。

所以,一旦发现问题,从 Java 端重新创建流程是一件简单的事情,我创建了一个新的 Bouncy Castle Engine 扩展 CAST5Engine 并替换了 setKey 和 encryptBlock 方法。您可以查看this gist 以了解其工作原理。

关键是reverseByteArrayByBlock,被多次调用。与 PHP 完全相同。

如果您不太熟悉 Bouncy Castle 的工作原理(加密/解密函数假定您的密钥是十六进制编码),您还可以在 Gist 中查看如何使用 PHPCast256Crypter.java 文件中的类。

祝你好运!

【讨论】:

  • 你刚刚拯救了我的一天!非常感谢你
猜你喜欢
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-17
  • 2011-10-09
  • 2012-05-06
  • 1970-01-01
  • 2013-08-24
相关资源
最近更新 更多