通过 UDP 发送 RC4 加密数据会导致解密明文发生变化
Posted
技术标签:
【中文标题】通过 UDP 发送 RC4 加密数据会导致解密明文发生变化【英文标题】:Sending RC4 encrypted data over UDP causes changes in decrypted plaintext 【发布时间】:2020-07-28 23:44:52 【问题描述】:我正在尝试使用 Java 通过 UDP 连接发送一些数据。
在客户端,我使用返回字符串的 RC4 算法加密数据。这个字符串,我转换成字节数组,作为数据报包发送。
但是,在服务器端,解密后的明文给出的结果与原始文本相似,但有一些不同。
当我独立运行 RC4 加密程序并且客户端和服务器使用相同的源代码时,它运行良好,所以我真的不明白为什么会发生这种情况。
这是客户端的代码:
import java.net.*; import javax.crypto.Cipher; import java.io.*; import java.security.*; import java.security.spec.*; import java.util.*; import java.util.Base64.*;
class EchoClient
public static void main( String args[] ) throws Exception
Scanner sc = new Scanner (System.in);
DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(120000);
//Encrypting and sending data
System.out.print("Enter data: ");
String password = sc.nextLine();
String credentials = password;
String encryptedCredentials = RC4.encryptRC4(credentials, "637443");
byte encCred[] = encryptedCredentials.getBytes();
DatagramPacket packetCred = new DatagramPacket(encCred,encCred.length,InetAddress.getByName(args[0]),1500);
socket.send(packetCred);
System.out.println("\nEncrypted Credentials sent");
System.out.println("Plain: " + credentials);
System.out.println("Encrypted data: " + encryptedCredentials);
这是服务器:
import java.net.*; import javax.crypto.Cipher; import java.io.*; import java.security.*; import java.security.spec.*; import java.util.*; import java.util.Base64.*;
class EchoServer
public static void main( String args[] ) throws Exception
System.out.println("Server running. Awaiting Connection Request...\n");
Scanner sc = new Scanner (System.in);
DatagramSocket socket = new DatagramSocket(1500);
//Recieving Credentials
DatagramPacket packetCred = new DatagramPacket(new byte[512],512);
socket.receive(packetCred);
String stringCred = new String(packetCred.getData(),0,packetCred.getLength());
String decryptedCred = RC4.decryptRC4(stringCred, "637443");
System.out.println("\nReceived Authentication Data");
System.out.println("Bob at: "+new Date()+" "+packetCred.getAddress()+":"+packetCred.getPort()+"\nData: "+new String(packetCred.getData(),0,packetCred.getLength()));
System.out.println("Decrypted Credentials: " + decryptedCred);
这是客户端输出:
输入数据:你好。怎么样了?我很好;谢谢。
正在设置 RC4...
开始 RC4 加密...
加密完成:
已发送加密凭据
Plain:你好。怎么样了?我很好;谢谢。
加密数据:?d¥érSÿ?dNé?=P°?Whéá=Nù?H!)îërC??f@?ï
这是服务器终端输出:
服务器正在运行。正在等待连接请求...
正在设置 RC4...
开始 RC4 解密...
解密完成:
收到的认证数据
鲍勃时间:2020 年 7 月 29 日星期三 05:01:51 IST /127.0.0.1:54835
数据:?d¥érSÿ?dNé?=P°?Whéá=Nù?H!)îërC??f@?ï
解密的凭据:你好。 How'Æ it goinÆ?我很好; 谢谢。
【问题讨论】:
问题是String
不是二进制数据的容器。您的解密方法应该有一个字节数组参数,而不是String
。你为什么使用RC4?它已被弃用多年,并于 2015 年被 IETF 禁止用于 TLS。
欢迎来到 ***。所有常规加密算法都基于字节数组作为 INPUT 和 OUTPUT 的源。您的 RC4 方法确实有输入字符串和返回字符串。请编辑您的问题并向我们展示用于加密和解密的 RC4 方法。我敢肯定,您的问题与其他 cmets/answers 争论的问题一样。
【参考方案1】:
我认为这是字符串编码的问题。除非您绝对确定两端使用相同的平台编码,否则切勿在未指定编码的情况下使用 String.getBytes()
。
在需要转换byte[]/String
的任何地方(RC4.decryptRC4()/RC4.encryptRC4()
、new String()
、String.getBytes()
)都这样做:
从String
到byte[]
:.getBytes(StandardCharsets.UTF_8)
从byte[]
到String
:new String(byte[], int, int, StandardCharsets.UTF_8)
UTF-8 还是 ISO-8859-1 并不重要,只要两端相同。
哦,正如@MarquisofLorne 所说,请不要使用 RC4,除非它仅用于教育目的。
【讨论】:
这真的很有帮助。非常感谢你!下次在字节数组和字符串之间转换时,我会一直使用它。 是的,我正在使用 RC4 进行网络协议分配。我们的老师说他不关心RC4加密,只要它有效并且协议是正确的。再次感谢!以上是关于通过 UDP 发送 RC4 加密数据会导致解密明文发生变化的主要内容,如果未能解决你的问题,请参考以下文章