我想使用此密钥C6864E7696C686和DES算法加密挑战(如162236fe0bec620827958c8fdf7e4bc7)。
这是我的代码:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.xml.bind.DatatypeConverter;
import javax.crypto.spec.DESKeySpec;
def data = prev.getResponseData();
String challenge = javax.xml.bind.DatatypeConverter.printHexBinary(data);
final String strPassPhrase = "C6864E7696C686";
String param = challenge;
System.out.println("Text : " + param);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(hexStringToByteArray(strPassPhrase)));
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
String str = DatatypeConverter.printBase64Binary(cipher.doFinal(param.getBytes()));
System.out.println("Text Encryted : " + str);
cipher.init(Cipher.DECRYPT_MODE, key);
String str2 = new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(str)));
System.out.println("Text Decryted : " + str2);
但我得到了这个例外:
java.security.InvalidKeyException: Wrong key size
修改: 我已复制此函数以将我的十六进制字符串转换为字节:
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
但我得到同样的例外......
答案 0 :(得分:4)
您的DES密钥应为8个字节(56位+ 8个奇偶校验位)。
您作为键使用的字符串看起来像是7字节的十六进制表示,但不是将其解码为十六进制,而是获取十六进制字符串中字符的字节。
由于有14个字符,您最有可能(取决于您的编码)最终得到14个字节,这对于DES来说太长了。
this question中描述了几种解释如何将十六进制字符串转换为字节数组的方法。
然而,这只会让你到目前为止,因为你仍然只有一个字节短。传统的方法似乎是采用你拥有的56位并将它们扩展到8个字节以上,为每个字节添加一个奇偶校验位。 this answer中描述了如何执行此操作的Java示例。另一种方法可能是在密钥的末尾添加一个null
字节。您应采取哪种方法取决于密钥的预期用途,尤其是您与其他方交换信息的方式。