DES密文长度在传输过程中减少,不是8字节的倍数
DES ciphertext length decreased during transmission and is not a multiple of 8 bytes
一个项目尝试用DES算法加密一个pwd。
当我尝试这个时
private static String key = "my8bcode"; /*Key 8 bytes or 56 bit supported by algo OF*/
private static byte[] byteKey = key.getBytes();
public static void main(String[] args) throws Exception {
String ss = "yuyuvdzdsfdsfsdsdsdsdsa";
byte[] plainText = ss.getBytes();//Conversion en byte
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // Request the use of the DES algorithm, using the ECB mode (Electronic CodeBook) and style padding PKCS-5.
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] myCipherText = cipher.doFinal(plainText);
System.out.println(new String(myCipherText, "UTF8"));
System.out.println(myCipherText.length);
System.out.println("\nStart decryption");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] newPlainText = cipher.doFinal(myCipherText);
System.out.println(new String(newPlainText, "UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
我没有遇到任何问题,但为了更进一步,我尝试使用以下代码在两个单独的步骤中执行此操作:
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //Request the use of the DES algorithm, using the ECB mode (Electronic CodeBook) and style padding PKCS-5.
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] myCipherText = cipher.doFinal(plainText);
byte[] test = (new String(myCipherText, "UTF8")).getBytes();
System.out.println("\nStart decryption");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] newPlainText = cipher.doFinal(test);
System.out.println(new String(newPlainText, "UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
它不起作用,我的控制台中有这条消息:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8
确实,test[]的长度是7,不是8,怎么可能?
为什么我在转录过程中丢失了一个字节?
请帮助我理解并解决我的问题;)
byte[]
和 String
应该分开。主要错误是随机字节序列(加密文本)可能很容易 不正确的 UTF-8。 UTF-8是一种多字节格式,其中高位以指定的方式标记多字节序列,例如10xxxxxx
是一个连续字节。
但是要加密一个字符串(Unicode),使用UTF-8是非常合适的。单字节编码是有损的;假设文本是否同时包含希腊语和保加利亚语。
byte[] data = text.getBytes(StandardCharsets.UTF_8);
text = new String(data, StandardCharsets.UTF_8);
这些是 String
构造函数和 getBytes
方法的重载版本,指定了字符集。否则它依赖于平台,因此与另一台计算机的通信是灾难性的。
但是一旦你有了二进制数据,byte[]
,不要把它转换成 (Unicode) 字符串,是一个(昂贵的)转换,冗余且容易出错。
因此人们经常看到将二进制数据额外转换为 Base64,接收更长的 ASCII 字符串。
我就是这么做的(删除 UTF 8 规范),经过大量测试后它可以正常工作了:
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //Demande l'utilisation de l'algorithme DES, en utilisant le mode ECB (Electronic CodeBook) et le style de padding PKCS-5.
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] myCipherText = cipher.doFinal(plainText);
byte[] test = (new String(myCipherText)).getBytes();
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] newPlainText = cipher.doFinal(test);
System.out.println(new String(newPlainText));
} catch (Exception e) {
e.printStackTrace();
}
非常感谢
一个项目尝试用DES算法加密一个pwd。
当我尝试这个时
private static String key = "my8bcode"; /*Key 8 bytes or 56 bit supported by algo OF*/
private static byte[] byteKey = key.getBytes();
public static void main(String[] args) throws Exception {
String ss = "yuyuvdzdsfdsfsdsdsdsdsa";
byte[] plainText = ss.getBytes();//Conversion en byte
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // Request the use of the DES algorithm, using the ECB mode (Electronic CodeBook) and style padding PKCS-5.
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] myCipherText = cipher.doFinal(plainText);
System.out.println(new String(myCipherText, "UTF8"));
System.out.println(myCipherText.length);
System.out.println("\nStart decryption");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] newPlainText = cipher.doFinal(myCipherText);
System.out.println(new String(newPlainText, "UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
我没有遇到任何问题,但为了更进一步,我尝试使用以下代码在两个单独的步骤中执行此操作:
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //Request the use of the DES algorithm, using the ECB mode (Electronic CodeBook) and style padding PKCS-5.
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] myCipherText = cipher.doFinal(plainText);
byte[] test = (new String(myCipherText, "UTF8")).getBytes();
System.out.println("\nStart decryption");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] newPlainText = cipher.doFinal(test);
System.out.println(new String(newPlainText, "UTF8"));
} catch (Exception e) {
e.printStackTrace();
}
它不起作用,我的控制台中有这条消息:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8
确实,test[]的长度是7,不是8,怎么可能?
为什么我在转录过程中丢失了一个字节?
请帮助我理解并解决我的问题;)
byte[]
和 String
应该分开。主要错误是随机字节序列(加密文本)可能很容易 不正确的 UTF-8。 UTF-8是一种多字节格式,其中高位以指定的方式标记多字节序列,例如10xxxxxx
是一个连续字节。
但是要加密一个字符串(Unicode),使用UTF-8是非常合适的。单字节编码是有损的;假设文本是否同时包含希腊语和保加利亚语。
byte[] data = text.getBytes(StandardCharsets.UTF_8);
text = new String(data, StandardCharsets.UTF_8);
这些是 String
构造函数和 getBytes
方法的重载版本,指定了字符集。否则它依赖于平台,因此与另一台计算机的通信是灾难性的。
但是一旦你有了二进制数据,byte[]
,不要把它转换成 (Unicode) 字符串,是一个(昂贵的)转换,冗余且容易出错。
因此人们经常看到将二进制数据额外转换为 Base64,接收更长的 ASCII 字符串。
我就是这么做的(删除 UTF 8 规范),经过大量测试后它可以正常工作了:
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(byteKey, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); //Demande l'utilisation de l'algorithme DES, en utilisant le mode ECB (Electronic CodeBook) et le style de padding PKCS-5.
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] myCipherText = cipher.doFinal(plainText);
byte[] test = (new String(myCipherText)).getBytes();
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] newPlainText = cipher.doFinal(test);
System.out.println(new String(newPlainText));
} catch (Exception e) {
e.printStackTrace();
}
非常感谢