Java AES解密 中文乱码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java AES解密 中文乱码相关的知识,希望对你有一定的参考价值。
如图是解密出来的TXT文件,可以看见英文、数字都是正常的,但是中文就是乱码。。加密的时候读取的是ANSI编码的TXT文件,解密输出的是UTF-8编码的文件。有办法吗?
这个不一定是错误的。你把你的txt文件拖到ie窗口,然后换不同的编码去看看。说不定是正确的,只是编码notepad不认而已。追问用IE打开是这样的:
锟斤拷+86 135 2382 25
锟斤拷汀锟斤拷师+86136115042
锟斤拷汀锟斤拷师+86136115042
Tom (iPhone)+86138141689
Tom (iPhone)+86138141689
薛锟斤拷锟斤拷+86138514275
薛锟斤拷锟斤拷+86138514275
仍然是乱码。。
IE里右键,选择编码,分别试试 utf-8 gbk big5等
参考技术A 文件——另存为——选择编码,然后打开看看 参考技术B 肯定是编码不对了。java中的Aes解密-填充问题
【中文标题】java中的Aes解密-填充问题【英文标题】:Aes decryption in java - problems with padding 【发布时间】:2016-09-03 02:15:41 【问题描述】:我想用java实现一个简单的加密/解密工具。 因此我找到了一个小教程:http://www.codejava.net/coding/file-encryption-and-decryption-simple-example
我更改了一些代码行,以保证大文件的加密。 现在我遇到了问题,解密不起作用。
我收到以下错误消息/异常:
Error encrypting/decrypting file
at Algorithmus.Encryptor.doCrypto(Encryptor.java:71)
at Algorithmus.Encryptor.decrypt(Encryptor.java:39)
at GUI.MainWindow$encryptThread.run(MainWindow.java:838)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at Algorithmus.Encryptor.doCrypto(Encryptor.java:60)
... 2 more
我尝试将 Transoformation 参数更改为 AES/CBC/PKCS5Padding
,但这没有任何效果。有谁知道,如何优化给定的代码?
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION = "AES";
public static void encrypt(String key, File inputFile, File outputFile)
throws ExtendedException
doCrypto(Cipher.ENCRYPT_MODE, key, inputFile, outputFile);
public static void decrypt(String key, File inputFile, File outputFile)
throws ExtendedException
doCrypto(Cipher.DECRYPT_MODE, key, inputFile, outputFile);
private static void doCrypto(int cipherMode, String key, File inputFile,
File outputFile) throws ExtendedException
try
Key secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(cipherMode, secretKey);
FileInputStream inputStream = new FileInputStream(inputFile);
CipherOutputStream out = new CipherOutputStream(new FileOutputStream(outputFile), cipher);
byte[] buffer = new byte[8192];
byte[] outputBytes = null;
FileOutputStream outputStream = new FileOutputStream(outputFile);
int count;
while ((count = inputStream.read(buffer)) > 0)
out.write(buffer, 0, count);
outputBytes = cipher.doFinal(buffer);
inputStream.close();
outputStream.close();
catch (NoSuchPaddingException | NoSuchAlgorithmException
| InvalidKeyException | BadPaddingException
| IllegalBlockSizeException | IOException ex)
throw new ExtendedException("Error encrypting/decrypting file", ex);
【问题讨论】:
【参考方案1】:只需使用CipherOutputStream
。不要调用cipher.doFinal(buffer)
,也不要忘记关闭输出流。
FileInputStream inputStream = new FileInputStream(inputFile);
FileOutputStream fileout = new FileOutputStream(outputFile);
CipherOutputStream out = new CipherOutputStream(fileout , cipher);
try
byte[] buffer = new byte[8192];
int count;
while ((count = inputStream.read(buffer)) > 0)
out.write(buffer, 0, count);
finally
out.close();
inputStream.close();
CipherOutputStream
为您管理密码。当流将被关闭并刷新内部缓冲区时,它会调用doFinal
。
【讨论】:
非常感谢。它完美地工作!但是,如果我输入了错误的密码,则不会抛出异常。将创建解密文件,但人类不可读 @jollepe AES/CBC 加密本身不提供正确密码的验证,如果您需要添加加密数据的 MAC 并将其用于验证或使用 AES/GCM。必须避免向用户返回错误填充错误,否则攻击者可以在填充预言攻击中利用它。以上是关于Java AES解密 中文乱码的主要内容,如果未能解决你的问题,请参考以下文章