[英]Sending RC4 encrypted data over UDP causes changes in decrypted plaintext
I'm trying to send some data across a UDP connection using Java.我正在尝试使用 Java 通过 UDP 连接发送一些数据。
At the Client, I encrypt the data with an RC4 algorithm which returns a string.在客户端,我使用返回字符串的 RC4 算法加密数据。 This string, I convert to a byte array and send it as a Datagram Packet.我将此字符串转换为字节数组并将其作为数据报包发送。
However, at the Server, the decrypted plaintext gives a result similar to the original but with some differences.然而,在服务器端,解密后的明文给出的结果与原始文本相似,但有一些不同。
The RC4 encryption program works fine when I run it independently and both Client and Server use the same source code so I really don't understand why this is happening.当我独立运行 RC4 加密程序并且客户端和服务器都使用相同的源代码时,它工作正常,所以我真的不明白为什么会发生这种情况。
Here's the code for the Client side:这是客户端的代码:
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);
}
}
And here's the Server:这是服务器:
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);
}
Here's the Client terminal output:这是客户端 output:
Enter data: Hello there.输入数据:你好。 How's it going?怎么样了? I'm doing fine;我很好; thanks.谢谢。
Setting up RC4...正在设置 RC4...
Starting RC4 encryption...开始 RC4 加密...
Encryption Complete:加密完成:
Encrypted Credentials sent发送的加密凭证
Plain: Hello there.平原:你好。 How's it going?怎么样了? I'm doing fine;我很好; thanks.谢谢。
Encrypted data: ?d ¥érSÿ?dNé?=P°?Whéá=Nù?H?)îërC??f@?ï<B¬?i?í!加密数据: ?d ¥érSÿ?dNé?=P°?Whéá=Nù?H?)îërC??f@?ï<B¬?i?í!
And here's the Server terminal output:这是服务器终端 output:
Server running.服务器运行。 Awaiting Connection Request...正在等待连接请求...
Setting up RC4...正在设置 RC4...
Starting RC4 decryption...开始 RC4 解密...
Decryption Complete:解密完成:
Received Authentication Data接收到的认证数据
Bob at: Wed Jul 29 05:01:51 IST 2020 /127.0.0.1:54835 Bob 于:Wed Jul 29 05:01:51 IST 2020 /127.0.0.1:54835
Data: ?d ¥érSÿ?dNé?=P°?Whéá=Nù?H?)îërC??f@?ï<B¬?i?í!数据:?d ¥érSÿ?dNé?=P°?Whéá=Nù?H?)îërC??f@?ï<B¬?i?í!
Decrypted Credentials: Hello thÆre.解密凭证:你好。 How'Æ it goinÆ? How'Æ it goinÆ? I'm doÆng fine;我很好; thanks.谢谢。
I think it's a problem with string encoding.我认为这是字符串编码的问题。 Never use String.getBytes()
without specifying an encoding unless you're absolutely sure that both ends use the same platform encoding.除非您绝对确定两端使用相同的平台编码,否则切勿在未指定编码的情况下使用String.getBytes()
。
Everywhere ( RC4.decryptRC4()/RC4.encryptRC4()
, new String()
, String.getBytes()
) where you need to convert byte[]/String
do this:在需要转换byte[]/String
的任何地方( RC4.decryptRC4()/RC4.encryptRC4()
, new String()
, String.getBytes( String.getBytes()
)执行以下操作:
From String
to byte[]
: .getBytes(StandardCharsets.UTF_8)
从String
到byte[]
.getBytes(StandardCharsets.UTF_8)
From byte[]
to String
: new String(byte[], int, int, StandardCharsets.UTF_8)
从byte[]
到String
: new String(byte[], int, int, StandardCharsets.UTF_8)
It doesn't really matter if it's UTF-8 or ISO-8859-1, as long as it is the same in both ends . UTF-8 还是 ISO-8859-1 无所谓,只要两端相同即可。
Oh, as @MarquisofLorne said, please don't use RC4 unless its for educational purposes only.哦,正如@MarquisofLorne 所说,请不要使用 RC4,除非它仅用于教育目的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.