Padding added while converting from DatagramPacket to byte array.

huangapple go评论83阅读模式
英文:

Padding added while converting from DatagramPacket to bye array

问题

你好,这里是您的中文翻译:

在Java中,我正在尝试从UDP服务器传递RSA公钥给客户端。为此,在服务器端生成了一个公钥,将其转换为字节数组,然后将其作为DatagramPacket传递给客户端。不幸的是,在客户端,尽管接收到的数据包大小与发送的数据包大小相同,但在将数据包数据保存到字节数组后,大小会显著增加,并添加了一些填充数据。如何去除这些填充数据?

这是服务器端的代码:

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");
        
        DatagramSocket socket = new DatagramSocket(1500);
        
        // 接收用户名
        DatagramPacket packetU = new DatagramPacket(new byte[512], 512);
        socket.receive(packetU);
        
        // 生成密钥对
        System.out.println("Generating Key Pair");
        KeyPair pair = RSA.generateKeyPair();
        byte[] encodedPrivateKey = pair.getPrivate().getEncoded();
        byte[] encodedPublicKey = pair.getPublic().getEncoded();
        
        System.out.println("\nPublic Key: " + Base64.getEncoder().encodeToString(encodedPublicKey));
        
        // 发送公钥
        System.out.println("Sending Public Key");
        DatagramPacket packetPK = new DatagramPacket(encodedPublicKey, encodedPublicKey.length, packetU.getAddress(), packetU.getPort());
        socket.send(packetPK);
        System.out.println("Packet length: " + packetPK.getLength());
    }
}

以及客户端的代码:

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);
        
        // 初始化身份验证
        System.out.print("Enter username: ");
        String username = sc.nextLine();            
        byte[] uname = username.getBytes();
        DatagramPacket packetU = new DatagramPacket(uname, uname.length, InetAddress.getByName(args[0]), 1500);
        socket.send(packetU);
        
        // 接收公钥
        System.out.println("Public Key Received");
        DatagramPacket packetPK = new DatagramPacket(new byte[512], 512);
        socket.receive(packetPK);
        byte[] publicKey = packetPK.getData();
        System.out.println("Packet length: " + packetPK.getLength());
        System.out.println("Byte[] length: " + publicKey.length);
        System.out.println("Alice at: " + new Date() + " " + packetPK.getAddress() + ":" + packetPK.getPort() + "\nPublic Key: " + Base64.getEncoder().encodeToString(publicKey));
    }
}

希望这有助于解决您遇到的问题。如果您有任何其他问题,请随时提问。

英文:

I'm trying to pass an RSA public key from a UDP Server to the client on Java.

For this, I generate a a public key at the Server, convert to a byte array and pass it as a DatagramPacket to the Client.

Unfortunately, at the Client side, while the packet received has the same size as the packet sent, after I save the packet data into a byte array, the size dramatically increases with some padding added after the received data.

How do I get rid of this padding?

Here's the code for 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");
DatagramSocket socket = new DatagramSocket(1500);
//Receive Username
DatagramPacket packetU = new DatagramPacket(new byte[512],512);
socket.receive( packetU );
//Generate Key Pair
System.out.println("Generating Key Pair");
KeyPair pair = RSA.generateKeyPair();
byte[] encodedPrivateKey = pair.getPrivate().getEncoded();
byte[] encodedPublicKey = pair.getPublic().getEncoded();
System.out.println("\nPublic Key: " + Base64.getEncoder().encodeToString(encodedPublicKey));
//Sending Public Key
System.out.println("Sending Public Key");
DatagramPacket packetPK = new DatagramPacket(encodedPublicKey,encodedPublicKey.length,packetU.getAddress(),packetU.getPort());
socket.send( packetPK );
System.out.println("Packet length: " + packetPK.getLength());
}
}

And for the Client:

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);
//Initiate Authentication
System.out.print("Enter username: ");
String username = sc.nextLine();			
byte[] uname = username.getBytes();
DatagramPacket packetU = new DatagramPacket(uname,uname.length,InetAddress.getByName(args[0]),1500);
socket.send( packetU );
//Recieving Public Key
System.out.println("Public Key Recieved");
DatagramPacket packetPK = new DatagramPacket(new byte[512],512);
socket.receive( packetPK );
byte[] publicKey = packetPK.getData();
System.out.println("Packet length: " + packetPK.getLength());
System.out.println("Byte[] length: " + publicKey.length);
System.out.println( "Alice at: "+new Date()+" "+packetPK.getAddress()+":"+packetPK.getPort()+"\nPublic Key: "+Base64.getEncoder().encodeToString(publicKey));
}
}

This is the output I receive at the Server terminal:

Server running. Awaiting Connection Request...

Generating Key Pair

Public Key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhYGTu7revdBCqdSm7ksM9qyagDirjsXtq52hPDdARoVbBNbZmZh4OoyNNorLqQqQzfF1oy9YtiDF4CLEip1t1T3oL2oRu1AQyIFlbbUyBoDh1jmvse0yAE2wcBumjZ1v8AvqV8tqzbn42uIaeBNjy3z5jLLx7NH80djSCHzkw1yCC+zs1uMJ8ZfuqPdDGqtOTskvw8qZ0LbhKcUFI1yLwkjlu1sVrZu1P86GTazEswV+B9f8255jyzS6AYR4+xosbvJpuyyQVahZ+LNRIAFFXnMe4BNX1WsT5hSlWOgtNy7NtKJSfXMts4RWJccZNznX8dRxZYPmZBEi7yI1WDHXkQIDAQAB
Sending Public Key
Packet length: 294

And the output at the Client terminal:

Enter username: Hello

Public Key Recieved

Packet length: 294

Byte[] length: 512

Alice at: Mon Jul 27 22:59:29 IST 2020 /127.0.0.1:1500

Public Key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhYGTu7revdBCqdSm7ksM9qyagDirjsXtq52hPDdARoVbBNbZmZh4OoyNNorLqQqQzfF1oy9YtiDF4CLEip1t1T3oL2oRu1AQyIFlbbUyBoDh1jmvse0yAE2wcBumjZ1v8AvqV8tqzbn42uIaeBNjy3z5jLLx7NH80djSCHzkw1yCC+zs1uMJ8ZfuqPdDGqtOTskvw8qZ0LbhKcUFI1yLwkjlu1sVrZu1P86GTazEswV+B9f8255jyzS6AYR4+xosbvJpuyyQVahZ+LNRIAFFXnMe4BNX1WsT5hSlWOgtNy7NtKJSfXMts4RWJccZNznX8dRxZYPmZBEi7yI1WDHXkQIDAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

答案1

得分: 0

在客户端,您获得了您分配的完整缓冲区,而不仅仅是发送的数据:

byte[] publicKey = packetPK.getData();

您还需要获取已发送数据的长度,然后仅打印数据缓冲区的该部分:

int len = packetPK.getLength();

参考链接:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/DatagramPacket.html#getData/

英文:

On the client side, you're getting the full buffer that you allocated, not just the data that was sent:

byte[] publicKey = packetPK.getData();

You need to also get the length of the data that was sent, and only print that portion of the data buffer:

int len = packetPK.getLength();

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/DatagramPacket.html#getData()

答案2

得分: 0

当您将字节数组转换为字符串时,您会看到您获得了一个正确的响应。尝试:

String x = new String(publicKey);
System.out.println(x);

所以您可以看到,正是字节数组中的空元素导致了问题。要么将publicKey转换为字符串然后使用它,要么截断您的字节数组以摆脱空白数组元素。两者都可以工作。

英文:

When you convert your byte array to String, you will see that you are getting a proper response. Try:

        String x = new String(publicKey);
System.out.println(x);

So you see, it's the empty elements of the byteArray which are causing the issue.
Either conver publicKey to String and then use it or truncate your byte array to get rid of blank array elements. Both will work

答案3

得分: 0

我已经弄清楚了。多亏了这里的答案,我进行了更多的研究,并发现与直接复制数据包到字节数组不同,我做了以下操作:

byte[] publicKey = new byte[packetPK.getLength()];
System.arraycopy(packetPK.getData(), packetPK.getOffset(), publicKey, 0, packetPK.getLength());

我考虑使用ArrayList是因为字节数组初始化为可变大小,但据我所知,上述方法也不是错误的,因为Java数组是动态的。

英文:

I've figured it out. Thanks to the answers here I did some more research and found that instead of directly copying the packet to the byte array, I did the following:

byte[] publicKey = new byte[packetPK.getLength()];
System.arraycopy(packetPK.getData(), packetPK.getOffset(), publicKey, 0, packetPK.getLength());

I thought of using an ArrayList because of the byte array is initialized to a variable size, but as far as I know, the method above isn't wrong either since Java arrays are dynamic.

huangapple
  • 本文由 发表于 2020年7月28日 01:36:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63120611.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定