加密密钥大小 DES Java
Encryption key size DES Java
我想使用密钥 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;
}
但我遇到了同样的异常...
您的 DES 密钥应为 8 个字节(56 位 + 8 个奇偶校验位)。
您用作键的字符串看起来像是 7 个字节的十六进制表示,但您不是将其解码为十六进制,而是获取十六进制字符串中字符的字节。
由于有 14 个字符,您很可能(取决于您的编码)以 14 个字节结束,这对于 DES 来说太长了。
this question 中描述了几种方法,解释了如何将十六进制字符串转换为字节数组。
然而,这只会让你走到这一步,因为你还少了一个字节。一种传统的方法似乎是将您拥有的 56 位分配给 8 个字节,并为每个字节添加一个奇偶校验位。 this answer 中描述了如何执行此操作的 Java 示例。另一种方法可能是在密钥末尾添加一个 null
字节。您应该采用哪种方法取决于密钥的预期用途,尤其是与您交换信息的其他方使用密钥的方式。
我想使用密钥 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;
}
但我遇到了同样的异常...
您的 DES 密钥应为 8 个字节(56 位 + 8 个奇偶校验位)。
您用作键的字符串看起来像是 7 个字节的十六进制表示,但您不是将其解码为十六进制,而是获取十六进制字符串中字符的字节。
由于有 14 个字符,您很可能(取决于您的编码)以 14 个字节结束,这对于 DES 来说太长了。
this question 中描述了几种方法,解释了如何将十六进制字符串转换为字节数组。
然而,这只会让你走到这一步,因为你还少了一个字节。一种传统的方法似乎是将您拥有的 56 位分配给 8 个字节,并为每个字节添加一个奇偶校验位。 this answer 中描述了如何执行此操作的 Java 示例。另一种方法可能是在密钥末尾添加一个 null
字节。您应该采用哪种方法取决于密钥的预期用途,尤其是与您交换信息的其他方使用密钥的方式。