Java BouncyCastle Cast6Engine(CAST-256)加密

我正在尝试实现一个接收字符串的函数,并返回CAST-256中String的编码值。 以下代码是我在BoncyCastle官方网页上的示例后实现的( http://www.bouncycastle.org/specifications.html ,第4.1点)。

import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.engines.CAST6Engine; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Base64; public class Test { static{ Security.addProvider(new BouncyCastleProvider()); } public static final String UTF8 = "utf-8"; public static final String KEY = "CLp4j13gADa9AmRsqsXGJ"; public static byte[] encrypt(String inputString) throws UnsupportedEncodingException { final BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CAST6Engine()); byte[] key = KEY.getBytes(UTF8); byte[] input = inputString.getBytes(UTF8); cipher.init(true, new KeyParameter(key)); byte[] cipherText = new byte[cipher.getOutputSize(input.length)]; int outputLen = cipher.processBytes(input, 0, input.length, cipherText, 0); try { cipher.doFinal(cipherText, outputLen); } catch (CryptoException ce) { System.err.println(ce); System.exit(1); } return cipherText; } public static void main(String[] args) throws UnsupportedEncodingException { final String toEncrypt = "hola"; final String encrypted = new String(Base64.encode(test(toEncrypt)),UTF8); System.out.println(encrypted); } } 

但是,当我运行我的代码时,我得到了

QUrYzMVlbx3OK6IKXWq1ng==

如果你使用相同的密钥在CAST-256中编码hola (如果你想要http://www.tools4noobs.com/online_tools/encrypt/,请尝试这里)我应该得到

w5nZSYEyA8HuPL5V0J29Yg==

发生什么事? 为什么我得到一个wront加密字符串?

我厌倦了在互联网上找到并没有找到答案。

Bouncy Castle默认使用PKCS#7填充,而PHP的mcrypt(以及您链接的网站)默认使用零填充。 这导致不同的密文。

请注意,此处使用的ECB模式几乎不能用于任何用途。 另外,我希望你发布的密钥不是真正的密钥,因为现在它不再是秘密,所有这些加密都是无用的。

这并没有真正回答你的问题,但确实提供了一些指示。

您需要进行一些挖掘以确保您以与PHP的mcrypt()完全相同的方式进行解密。 您需要确保密钥生成,编码/解码和密码算法完全匹配。

按键

 "CLp4j13gADa9AmRsqsXGJ".getBytes("UTF-8"); 

可能不是创建密钥源字节的正确方法。 文档似乎表明mcrypt()使用\0 mcrypt()键和数据,如果它不是正确的大小。 请注意,您的方法生成一个168位密钥,这不是一个有效的密钥大小,我不知道java会对它做什么。

算法
确保密码模式和填充是相同的。 mcrypt()是否使用ECB,CBC,还有其他什么?

编码
密码工作在字节上,而不是字符串。 确保两者之间的转换在java和PHP中是相同的。

以下是使用http://tools.ietf.org/html/rfc2612#page-10中的测试向量进行的CAST6参考测试。 注意密钥,密文和明文是hex编码的。

 import java.security.Provider; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class Cast6 { static final String KEY_ALGO = "CAST6"; static final String CIPHER_ALGO = "CAST6/ECB/NOPADDING"; static String keytext = "2342bb9efa38542c0af75647f29f615d"; static String plaintext = "00000000000000000000000000000000"; static String ciphertext = "c842a08972b43d20836c91d1b7530f6b"; static Provider bc = new BouncyCastleProvider(); public static void main(String[] args) throws Exception { System.out.println("encrypting"); String actual = encrypt(); System.out.println("actual: " + actual); System.out.println("expect: " + ciphertext); System.out.println("decrypting"); actual = decrypt(); System.out.println("actual: " + actual); System.out.println("expect: " + plaintext); } static String encrypt() throws Exception { Cipher cipher = Cipher.getInstance(CIPHER_ALGO, bc); byte[] keyBytes = Hex.decodeHex(keytext.toCharArray()); SecretKeySpec key = new SecretKeySpec(keyBytes, KEY_ALGO); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] input = Hex.decodeHex(plaintext.toCharArray()); byte[] output = cipher.doFinal(input); String actual = Hex.encodeHexString(output); return actual; } static String decrypt() throws Exception { Cipher cipher = Cipher.getInstance(CIPHER_ALGO, bc); byte[] keyBytes = Hex.decodeHex(keytext.toCharArray()); SecretKeySpec key = new SecretKeySpec(keyBytes, KEY_ALGO); cipher.init(Cipher.DECRYPT_MODE, key); byte[] output = cipher.doFinal(Hex.decodeHex(ciphertext.toCharArray())); String actual = Hex.encodeHexString(output); return actual; } }