【问题标题】:JAVA DES Encryption Output EncodingJAVA DES 加密输出编码
【发布时间】:2016-10-24 00:34:08
【问题描述】:

我在 JAVA (javax.crypto.Cipher) 中实现了 DES 加密算法,它成功地编码和解码(大多数)字符串......问题是,有时,它会消息特定的块(因为 DES 使用 8 个字符块模式下的块)。

在我的情况下,几乎总是第三块被搞砸了,其余的显示很好。

例如:

密钥:thisiskey

要加密的消息:Google is an American multinational technology company specializing in Internet-related services

加密消息(UTF-8):

mñqè•ÀPŒ�øf"
ߦ\±õ¤ù'È9¢ëyT ÍQEÁ|;ëâÉ÷JWú

现在,当我去解密这个时,我得到了这个:

解密消息:

Google i,í\O¯‹Ýbº-¸�¬ltinational technology company specializHôJ—=ÊÍnternet-related services

据我了解,这是由于 UTF-8 无法显示所有字符,因此在显示和复制以进行解密时,会出现此问题。

谁能给我一个解决方案? 最好是可以处理此问题的字符集,或者是一种将二进制直接转换为十六进制(可以输出给用户)然后在 JAVA 中反之亦然(在复制/粘贴后解密)的方法。

编辑 这是“近似”代码,不准确(例如,加密的消息不能正确粘贴,这些是函数的一部分,但它应该给出想法)。即使在 base64 编码中,我也无法正确解密。

Encrypt Function code:

boolean base64 = true;
key = "thisiskey";
plainText = "Google is an American multinational technology company specializing in Internet-related services";

SecretKeyFactory MyKeyFactory = SecretKeyFactory.getInstance("DES");
byte[] keyBytes = key.getBytes();

DESKeySpec generatedKeySpec = new DESKeySpec(keyBytes);
SecretKey generatedSecretKey = MyKeyFactory.generateSecret(generatedKeySpec);

Cipher generatedCipher = Cipher.getInstance("DES");
generatedCipher.init(Cipher.ENCRYPT_MODE, generatedSecretKey);

byte[] messsageStringBytes = plainText.getBytes();
byte[] encryptedMessage = generatedCipher.doFinal(messsageStringBytes);

String encryptedMessageString = new String(encryptedMessage);

if (base64) {
    encryptedMessageString = Base64.getEncoder().encodeToString(encryptedMessageString.getBytes("utf-8"));
}

return encryptedMessageString;

解密函数代码:

boolean dbase64 = true;
dkey = "thisiskey";
messageToDecrypt = "mñqè•ÀPŒ�øf\"ߦ\±õ¤ù'È9¢ëyT ÍQEÁ|;ëâÉ÷JWú"; // Message from above code

SecretKeyFactory MyKeyFactory = SecretKeyFactory.getInstance("DES");
byte[] dkeyBytes = dkey.getBytes();

DESKeySpec generatedKeySpec = new DESKeySpec(dkeyBytes);
SecretKey generatedSecretKey = MyKeyFactory.generateSecret(generatedKeySpec);

Cipher generatedCipher = Cipher.getInstance("DES");
generatedCipher.init(Cipher.DECRYPT_MODE, generatedSecretKey);

if (dbase64) {
    byte[] decodedBytes = Base64.getDecoder().decode(dencryptedText);
    dencryptedText = new String(decodedBytes, "utf-8");
}

byte[] messsageStringBytes = dencryptedText.getBytes();
byte[] encryptedMessage = generatedCipher.doFinal(messsageStringBytes);

String decryptedMessageString = new String(encryptedMessage);

return decryptedMessageString;

【问题讨论】:

  • 没有你的代码,你怎么可能指望任何人能够帮助你?
  • DES 是一种很棒的加密算法——如果不需要安全的话。 DES 已被 AES 取代,请使用 AES。请不要创建糟糕的安全性,我们已经足够了。

标签: java encryption encoding utf-8


【解决方案1】:

“UTF-8 中的加密消息”毫无意义。密文是二进制而不是 UTF-8。您需要将其放入byte[],而不是String

如果您需要字符串,请使用Base64Hex 编码。


即使在 base64 编码中,我也无法正确解密。

String encryptedMessageString = new String(encryptedMessage);

if (base64) {
  encryptedMessageString =  Base64.getEncoder().encodeToString(encryptedMessageString.getBytes("utf-8"));
}

那行不通。在数据已经损坏(通过调用new String)后,您正在编码为 Base64。根本不要把它放在一个字符串中。直接从encryptedMessagebyte[])转到 Base64。

【讨论】:

  • 那么,您如何建议我“显示”文本以供使用/复制?你能帮忙吗?
  • 如果需要字符串,请使用 Base64 或 Hex 编码。有关详细信息,请参阅链接的线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
相关资源
最近更新 更多