我被要求在将一些文本发送到服务器端(java)之前加密来自客户端(web)的文本。
所以我尝试在客户端使用 CryptoJS 库。我像这样加密它:
var key = "aaaaaaaaaaaaaaaaaaaaaaaa";
var value = "KF169841";
var encryptedString = CryptoJS.TripleDES.encrypt(value, key);
console.log(encryptedString.toString());
我得到这样的东西:U2FsdGVkX19eYFFHgYGCr3v9/skTOKVp0pLWRNK9JTg=我在其他在线解密工具(也使用CryptoJS)中使用此加密字符串和密钥,并KF169841返回确切的值。
将此值和密钥发送到服务器后(好吧,密钥没有直接发送到服务器,但为了测试,它是),我需要使用 Java 解密它。但是我不知道如何解密它。我尝试了谷歌搜索中的一些代码,但如果使用 DESese,它最终会得到错误的填充,或者如果我使用 ECB/NoPadding,它最终会得到错误的值。我确实尝试了诸如为 CryptoJS 端设置 sfg 之类的东西,例如:
mode: CryptoJS.mode.EBC,
padding: CryptoJS.pad.NoPadding
但是他们得到了javascript异常(a不是定义)
所以任何有CryptoJS经验的人都可以帮助我使用java解密这个?
====
====================================================================更新:对不起,我正在使用的服务器端代码
/**
* Method To Decrypt An Ecrypted String
*/
public String decrypt(String encryptedString, String myEncryptionKey) {
String decryptedText = null;
try {
byte[] keyAsBytes = myEncryptionKey.getBytes("UTF8");
KeySpec myKeySpec = new DESedeKeySpec(keyAsBytes);
SecretKeyFactory mySecretKeyFactory =
SecretKeyFactory.getInstance("DESede");
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
SecretKey key = mySecretKeyFactory.generateSecret(myKeySpec);
cipher.init(Cipher.DECRYPT_MODE, key);
// BASE64Decoder base64decoder = new BASE64Decoder();
// byte[] encryptedText = base64decoder.decodeBuffer(encryptedString);
byte[] encryptedText = org.apache.commons.codec.binary.Base64.decodeBase64(encryptedString);
byte[] plainText = cipher.doFinal(encryptedText);
decryptedText= bytes2String(plainText);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
根据文档,您的encryptedString
变量包含结构化数据,必须将其拆分才能发送到 Java 代码。您需要向 Java 代码发送encryptedString.iv
和encryptedString.ciphertext
。如果您继续使用密码(见下文),您还需要发送encryptedString.salt
。
如果将密钥作为字符串传递,则将其解释为密码,并从中派生密钥。如果确实要传递显式密钥,请按照文档操作并按照以下代码片段的建议指定 IV 和密钥。如果您坚持提供密码,则必须找出派生方案并在 Java 代码中使用相同的过程。
// Code snippet from http://code.google.com/p/crypto-js/#Custom_Key_and_IV
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
var key = CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
var iv = CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');
var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });
</script>
关于你的Java代码,它看起来基本上没问题(尽管字符串转换有很大的错误空间)。但是,您可能希望将密钥从十六进制转换为二进制,而不是抓取字节:
byte[] keyAsBytes = DatatypeConverter.parseHexBinary(myEncryptionKey);
这假设您更改 JavaScript 代码以传递文本键值。
您还需要切换到 DESede/CBC/PKCS5Padding
并将 IVParameterSpec
对象传递给Cipher.init
调用,指定从 Java 脚本代码发送的 IV 值。