java - RSA填充解密问题(聊天应用)
问题描述
我正在用 Java 为聊天应用程序编写代码,我必须实现加密算法。我正在使用 RSA,每个用户都有自己的密钥。当一个用户向其他用户发送消息时,应用程序将加密消息并将密码写入 .txt 文件。然后,应用程序将读取该 .txt 文件,解密文件并显示解密的密码......但我有错误
> javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:383)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:294)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2164)
at org.fastchat.User.readMessage(User.java:139)
at org.fastchat.ChatWith.<init>(ChatWith.java:80)
at org.fastchat.WatchInbox.startWatch(WatchInbox.java:75)
at org.fastchat.WatchInbox.run(WatchInbox.java:41)
我检查了密钥和消息,你能告诉我更多关于这个问题的信息吗?在收件箱中加密和写入消息的功能
public void sendMessage(User receiver, String message) throws Exception {
//Encrypter message, sent to receiver inbox
// Getting the public key from the key pair
PublicKey publicKey = receiver.getPub();
// Creating a Cipher object
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// Add data to the cipher
byte[] input = message.getBytes();
cipher.update(input);
// encrypting the data
byte[] cipherText = cipher.doFinal();
// System.out.println(new String(cipherText, "UTF8"));
BufferedWriter recFile=new BufferedWriter(new FileWriter(receiver.getInbox()+"/"+getUsername()+".txt"));
recFile.write(new String(cipherText,"UTF8"));
//DONT DELETE
//Make check file in receiver check folder, inbox check
BufferedWriter check=new BufferedWriter(new FileWriter(receiver.getCheck()+"/"+getUsername()+".txt"));
Random random=new Random();
Integer num=random.nextInt(20);
check.write(num.toString());
check.close();
recFile.close();
}
这是一个解密和读取消息的功能
public String readMessage(String msg) throws Exception{
// Creating a Cipher object
System.out.println("\n\n"+msg+"\n"); //!!!!!
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// Initializing the same cipher for decryption
cipher.init(Cipher.DECRYPT_MODE, getPriv());
// Decrypting the text
byte[] decipheredText = cipher.doFinal(msg.getBytes());
return new String(decipheredText,"UTF8");
}
我可以仅使用 .txt 文件使用 RSA 算法加密/解密,还是必须使用一些其他方法?
解决方案
是的,如果要将密文视为文本,则需要对密文进行 base 64 编码。密文由随机值的字节组成,并非每个字节都代表一个有效字符。
recFile.write(new String(cipherText,"UTF8"));
new String
上述行和解密过程中的都getBytes
可能导致字节丢失、更改甚至插入。
使用 UTF-8 作为实际字节的编码策略是个好主意。当前,您正在为纯文本消息使用平台编码:
byte[] input = message.getBytes();
这不是一个好主意,使用message.getBytes(StandardCharsets.UTF_8)
. 通过以这种方式指定字符集,您还可以避免不必要的异常处理,因为上述字符集始终存在,因此在编译时验证正确性。
推荐阅读
- flutter - 徽章上的三元运算符仅在有新消息时显示徽章
- python - 代码在某些条件下需要永远执行。需要跑得更快
- sql - 填充函数给出(空值被聚合或其他 SET 操作消除)错误
- excel - 如何通过excel宏向图表添加文本?
- android - 返回改造响应的实时数据有什么好处
- algorithm - 死锁避免算法
- bash - 检查系统日期
- react-native - Expo ImagePicker在取消时卡在ActivityIndicator上
- scala - 向 SBT 项目添加 Maven 依赖项
- windows - Start-Transcript 的 Powershell 问题