我正在编写一个程序,我从输出套接字创建的密钥对中发送密钥的字节,并使用它们在另一端重新创建密钥。 服务器:
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);
客户:
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);
然而,在这一行我收到一个错误:
PublicKey dsaKey = dsakeyFactory.generatePublic(dsaspec);
错误本身的跟踪:
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)
我已经研究过并且我已经看到EOF发生了,因为没有足够的字节来创建密钥,这让我相信它是如何发送字节的问题。我是否错误地发送了字节?
答案 0 :(得分:1)
输入流中的输入流中丢失的字节
未读字节。您假设read()
填充了缓冲区。它没有义务这样做。使用DataInputStream.readFully()
。
您还可以使用write(int)
和read()
无参数限制自己使用128个关键字节来发送/接收长度字。请使用DataOutputStream.writeInt()
和DataInputStream.readInt()
。
答案 1 :(得分:0)
假设您的第一个字节没有发送关键字节数组的大小,或者您使用的是大小超过256位的密钥,那么该数组将不完整。 尝试使用writeLong()或writeInt()的DataOutputStream方法发送字节大小以启动正确大小的数组。其次尝试使用缓冲区来读取它的发送时间。
以下是我的文件套接字发送者的一些代码: 这是发送部分:
OutputStream os = sock.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeInt(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
这是收到的部分:
InputStream in = sock.getInputStream();
DataInputStream dis = new DataInputStream(in);
int byteSize = clientData.readInt();
byte[] byteData = new Byte[byteSize];
dis.read(byteData);
您可能希望通过使用DIS read(byte[],int,int)
的方法告知要读取多少字节来缓冲接收部分,直到读取所有字节为止。我在同一台计算机上使用非常小的数据测试了我的代码,因此连接稳定性不是一个因素。