简体   繁体   English

通过 UDP 发送 RC4 加密数据会导致解密明文发生变化

[英]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)Stringbyte[] .getBytes(StandardCharsets.UTF_8)

From byte[] to String : new String(byte[], int, int, StandardCharsets.UTF_8)byte[]Stringnew 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM