Java 中十六进制密钥、IV 和数据的 AES 加密
AES encryption for hex key, IV and data in Java
我必须使用密钥和 IV 将十六进制字符串加密为十六进制数据。请在下面找到我使用的代码。问题是我需要加密的字符串是明文。我需要将明文转换为十六进制,但我不知道该怎么做。谁能帮帮我??
我一直在用webtool确认,
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");
}
以上数据我应该得到,
b6 06 da b9 cd dc 2d 89 4b 49 0a ab 4e e7 dc 58
而是我得到了,
e3 62 34 3f 广告 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 编码。
Encoding/decoding 最好使用 Apache Commons Codec、Guava、Bouncy Castle 等库来执行,Java 8 仍然不十六进制 encode/decode 字节数组(唉).
我创建了一个小代码示例,输出十六进制格式,就好像它是 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);
}
我必须使用密钥和 IV 将十六进制字符串加密为十六进制数据。请在下面找到我使用的代码。问题是我需要加密的字符串是明文。我需要将明文转换为十六进制,但我不知道该怎么做。谁能帮帮我??
我一直在用webtool确认,
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");
}
以上数据我应该得到,
b6 06 da b9 cd dc 2d 89 4b 49 0a ab 4e e7 dc 58
而是我得到了,
e3 62 34 3f 广告 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 编码。
Encoding/decoding 最好使用 Apache Commons Codec、Guava、Bouncy Castle 等库来执行,Java 8 仍然不十六进制 encode/decode 字节数组(唉).
我创建了一个小代码示例,输出十六进制格式,就好像它是 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);
}