-1

I'm writing a program where I send bytes of a key from a keypair that I created over an output socket and use them to recreate the key on the other side. Server:

    KeyPairGenerator dsaKeyPairGenerator = 
    KeyPairGenerator.getInstance("DSA");
    dsaKeyPairGenerator.initialize(1024);
    KeyPair dsakeyPair = dsaKeyPairGenerator.generateKeyPair();
    PrivateKey dsaPrivate = dsakeyPair.getPrivate();
    PublicKey dsaPublic = dsakeyPair.getPublic();
    byte[] dsaPublicbytes = dsaPublic.getEncoded();
    clientSocket.getOutputStream().write(dsaPublicbytes.length);
    clientSocket.getOutputStream().write(dsaPublicbytes);

Client:

    int dsalength = clientSocket.getInputStream().read();
    byte[] dsaPublicbytes = new byte[dsalength];
    clientSocket.getInputStream().read(dsaPublicbytes);
    X509EncodedKeySpec dsaspec = new X509EncodedKeySpec(dsaPublicbytes);
    KeyFactory dsakeyFactory = KeyFactory.getInstance("DSA");
    PublicKey dsaKey = dsakeyFactory.generatePublic(dsaspec);

However, on this line I get an error:

    PublicKey dsaKey = dsakeyFactory.generatePublic(dsaspec);

The trace for the error itself:

Exception in thread "main" java.security.spec.InvalidKeySpecException: Inappropriate key specification: IOException: Detect premature EOF
at sun.security.provider.DSAKeyFactory.engineGeneratePublic(DSAKeyFactory.java:119)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at Client.main(Client.java:36)

I have researched and I've seen that the EOF occurs because there aren't enough bytes to create the key, which leads me to believe that it is a problem with how I am sending the bytes. Am I sending the bytes incorrectly?

Venki WAR
  • 1,997
  • 4
  • 25
  • 38
  • Have you compared how many bytes you are sending to the number you are receiving? What have you done to try to debug the problem? Have you remembered that bytes are signed? – tgdavies May 07 '18 at 03:47
  • I have printed out the bytes on both sides and there are less bytes after they have been written to the output stream. And do you mean that I should attempt to used unsigned bytes instead? I have attempted using the .available() method instead of .read and got a DER input, integer tag error instead. – Boosted Nero May 07 '18 at 04:23
  • How many bytes shpuld be sent? How many are received? Which ones are missing? – tgdavies May 07 '18 at 05:51
  • How can there be 'less bytes after they have been written to the output stream'? What does this statement even mean? – user207421 May 07 '18 at 08:09

2 Answers2

1

Lost bytes in input stream

Unread bytes in input stream. You assumed that read() filled the buffer. It isn't obliged to do that. Use DataInputStream.readFully().

You're also limiting yourself to 128 key bytes by using write(int), and read() with no parameters, for sending/receiving the length word. Use DataOutputStream.writeInt() and DataInputStream.readInt() for that.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

Assuming that your first byte is not sending the size of key byte array or you are using the key that has size bigger than 256-bit, then the array will be incomplete. Try using DataOutputStream methods of writeLong() or writeInt() to send byte size to initiate the right size array. Secondly try using buffers to read when its being send.

Here is little bit of my code from my file socket sender: This is sending part:

    OutputStream os = sock.getOutputStream();
    DataOutputStream dos = new DataOutputStream(os);     
    dos.writeInt(mybytearray.length);   
    dos.write(mybytearray, 0, mybytearray.length);   

This is recieving part:

InputStream in = sock.getInputStream();
DataInputStream dis = new DataInputStream(in);
int byteSize = clientData.readInt();
byte[] byteData = new Byte[byteSize];
dis.read(byteData);

You may want to buffer receiving part by telling how many bytes to read using method of DIS read(byte[],int,int) until all of the bytes were read. I tested my code on same machine with very small size data so the connection stability was not a factor.

alikhtag
  • 316
  • 1
  • 6