加密邮件中带有问号的钻石是否正常?

时间:2018-05-25 11:02:22

标签: java encryption character aes

results_screenshot_image

byte[] originalMessage = MESSAGE.getBytes();
System.out.println("Byte[]: " + Arrays.toString(originalMessage));
System.out.println("Original: " + MESSAGE);
EnDat newEncryption = new EnDat(KEY);
byte[] encryptedTemp = newEncryption.getEncryptMessage(originalMessage);
System.out.println("Byte[]: " + Arrays.toString(encryptedTemp));
System.out.println("Encrypted: " + new String(encryptedTemp,0,encryptedTemp.length,StandardCharsets.UTF_8));
byte[] decryptedTemp = newEncryption.getDecryptMessage(encryptedTemp);
System.out.println("Byte[]: " + Arrays.toString(decryptedTemp));
System.out.println("Decrypted: " + new String(decryptedTemp,0,decryptedTemp.length,StandardCharsets.UTF_8));
public byte[] getEncryptMessage(byte[] msg) throws Exception {
    if(DEBUG_MODE) System.out.println(">>>ADDRESS: " + msg );
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    SecretKey secretKey = new SecretKeySpec(keyVal, ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    return cipher.doFinal(msg);
}
public byte[] getDecryptMessage(byte[] encryptedMsg) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    SecretKey secretKey = new SecretKeySpec(keyVal, ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    if(DEBUG_MODE) System.out.println(">>>ADDRESS: " + encryptedMsg );
    return cipher.doFinal(encryptedMsg);
}

之前我做过很少的加密,所以我尝试使用Java的Cipher类,结果发现一切正常,除了加密的消息结果看起来像带有问号的钻石的字符(其中有负char值)。加密是正常的,还是我的代码有什么问题?

2 个答案:

答案 0 :(得分:2)

加密输出假设看起来像随机垃圾。如果它清晰可辨,那么有人要么调整它看起来那样(比如用BASE64编码)或者出了什么问题。

此外,输出是二进制流。它并不意味着转换为String或打印,因为它不是文字。

所以这一行:

new String(encryptedTemp,0,encryptedTemp.length,StandardCharsets.UTF_8)

正在获取加密数据并尝试将其解释为UTF-8文本。但它不是UTF-8文本,所以你会得到奇怪的输出。

答案 1 :(得分:0)

是的,这是正常行为。

Java使用Unicode作为打印字符的编码。加密邮件时,它会在二进制级别加密,而不是在“valid-character”级别加密。这意味着,加密数据可能(并且常见)包含非字符值。当你试图打印它们时,你会得到一个 符号,这是......

  

用于替换未知,无法识别或无法代表的字符

From Wikipedia

如果您仍想查看加密数据,可以将数据保存到文件(例如使用java.io.FileOutputStream),然后使用能够显示二进制或十六进制值的程序打开它。
我推荐Sublime Text。它会自动识别二进制文件并按原样显示它们。

FileOutputStream fos = new FileOutputStream("pathname");
fos.write(encryptedByteArray);