我必须用密钥加密十六进制字符串,IV也作为十六进制数据。请在下面找到我使用的代码。问题是我需要加密的字符串是明文格式。我需要将明文转换为十六进制,但我不知道该怎么做。任何人都可以帮我吗?
我一直在使用网络工具进行确认,
http://aes.online-domain-tools.com/
static byte[] IV = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
static String plaintext = "00010101010102020202020303030303";
static byte[] encryptionKey = {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 };
public static void main(String[] args) {
try {
System.out.println("==Java==");
System.out.println("plain: " + plaintext);
byte[] cipher = encrypt(plaintext, encryptionKey);
System.out.print("cipher: ");
for (int i = 0; i < cipher.length; i++) {
// System.out.print(new Integer(cipher[i]) + " ");
byte b = cipher[i];
System.out.print(String.format("%02x", b & 0xFF) + " ");
}
String decrypted = decrypt(cipher, encryptionKey);
System.out.println("decrypt: " + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] encrypt(String plainText, byte[] encryptionKey)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV));
return cipher.doFinal(plainText.getBytes("UTF-8"));
}
public static String decrypt(byte[] cipherText, byte[] encryptionKey)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV));
return new String(cipher.doFinal(cipherText), "UTF-8");
}
对于上述数据,我应该得到,
B606 DA B9 CD DC 2D 89 4B 49 0A AB 4E E7 DC 58
但相反,我得到了,
E3 62 34 3F AD 8b 89 37 57 81 91 31 EE 79 49 52 26 BF 40 CB D0 CE 36 BD 8A 04 6B AF 34 D9 F3 D7
提前谢谢。
从中学到的最好的东西可能是,CBC(以及底层分组密码)等现代操作模式对二进制数据进行操作,通常作为一组字节提供。
从这个意义上说,最好尽可能坚持使用二进制数据。不要使用超过绝对必要的转换,并且仅在供人类使用时才使用十六进制编码。如果需要使用基于文本的表示形式传输二进制文件,则可以使用 Base 64 编码。
编码/解码最好使用Apache Commons Codec,Guava,Bouncy Castle等库来执行,Java 8仍然没有十六进制编码/解码字节数组(叹息)。
我创建了一个小代码示例,它输出十六进制格式,就好像它是 Java 字节数组文字一样。我会留给你创建不同的版本。
static byte[] IV = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
static byte[] plaintext = { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03 };
static byte[] encryptionKey = {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 };
public static void main(String[] args) {
try {
System.out.println("==Java==");
System.out.println("plain: " + toJavaHex(plaintext));
byte[] cipher = encrypt(plaintext, encryptionKey);
System.out.println("cipher: " + toJavaHex(cipher));
String decrypted = toJavaHex(decrypt(cipher, encryptionKey));
System.out.println("decrypt: " + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String toJavaHex(byte[] data) {
StringBuilder sb = new StringBuilder(13 * data.length);
for (int i = 0; i < data.length; i++) {
if (i != 0) {
sb.append(", ");
}
sb.append(String.format("(byte) 0x%02x", data[i]));
}
return sb.toString();
}
public static byte[] encrypt(byte[] plainText, byte[] encryptionKey)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV));
return cipher.doFinal(plainText);
}
public static byte[] decrypt(byte[] cipherText, byte[] encryptionKey)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV));
return cipher.doFinal(cipherText);
}