Java/PHP Encryption CAST-256


Java/PHP Encryption CAST-256

我有这个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在某种程度上是令人担忧的,但这只适用于遗留代码集成。

所以我终于明白了。

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

起初,我甚至无法重现与算法测试向量中的值相同的值,这让我神经崩溃。所以是时候看看PHP的源代码了。

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

我注意到php的实现,在将密钥和数据拆分为4个字节的块之后,它反转了这些块的内容。这在生成遮罩键和圆键时尤为重要,因为它们会因此而发生很大变化。

因此,一旦发现问题,从Java端重新创建流程就很简单了,我创建了一个新的Bouncy Castle引擎,扩展了CAST5Engine,并替换了setKey和encryptBlock方法。你可以看看这个要点,看看它是如何运作的。

关键是reverseByteArrayByByByBlock,它被调用多次。以与PHP完全相同的方式。

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

祝你好运!