【问题标题】:Use ObjectStreams over Sockets to transfer Java Key Object使用 ObjectStreams over Sockets 传输 Java Key Object
【发布时间】:2012-11-28 20:57:10
【问题描述】:

我正在尝试将 Key 类型的公钥对象发送到我的服务器。但我没有让这个运行。 prototocl 如下所示:

[命令]\n[序列化密钥对象]

客户端使用此代码:

Socket admin;
PrintWriter pw;
OutputStream os;
BufferedReader is; 
for(int tries = 0; tries < MAX_RECONNECT_TRIES_ADMIN_SERVER; tries++)
{
    try 
    {
        admin = new Socket(host,port);
        os = admin.getOutputStream();
        is = new BufferedReader(new InputStreamReader(admin.getInputStream()));
        pw = new PrintWriter(new OutputStreamWriter(os));   

        AdminServerCommand.NODE_REGISTER.writeToPrintWriter(pw);
        pw.flush();

        sendPublicKey(os);

        String resultLine = null;
        resultLine = is.readLine();
        if(AdminServer.Feedback.KEY_REGISTERED.commandMatch(resultLine))
        {
            is.close();
            os.close();
            admin.close();
            return true;
        }
        is.close();
        os.close();
        admin.close();
        registerNodeRetrySleep(1000);
    }
    catch (Exception e) 
    {}
}
return false;

public void sendPublicKey(OutputStream out)
{
    try
    {
        ObjectOutputStream outO = new ObjectOutputStream(out);
        outO.writeObject(cyper.getPublicKey());
        outO.flush();
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
}

public void writeToPrintWriter(PrintWriter os)
{
    if(os == null)
        throw new IllegalArgumentException("Can not write command to null stream.");
    os.println(comm);
    os.flush();
}

服务器使用

String com = "";
    try 
    {
        if(client.getInputStream().available() > 2)
        com = is.readLine();
    }
    catch (IOException e) 
    {
        errorResponse(Error.COMMAND_ERROR);
    }
    Key key = null;
    try
    {
        ObjectInputStream keyIn = new ObjectInputStream(client.getInputStream());
        key = (Key)keyIn.readObject();
    }
    catch(Exception b)
    {
        b.printStackTrace();
        errorResponse(Error.BAD_KEY);
        return;
    }

异常如下所示:

Nov 28, 2012 9:52:59 PM AdminServer.AdminServer run
INFO: Get a new request
java.io.StreamCorruptedException: invalid stream header: 73720014
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
    at java.io.ObjectInputStream.<init>(Unknown Source)
    at AdminServer.AdminServer.registerNewKeyEntry(AdminServer.java:115)
    at AdminServer.AdminServer.run(AdminServer.java:65)
    at java.lang.Thread.run(Unknown Source)
Nov 28, 2012 9:52:59 PM AdminServer.AdminServer errorResponse
WARNING: Error: Bad public key format. Use object stream with key object.

现在有没有人可以解决这个问题。类型 Key 是一个接口类型,它实现了自己的 Interface Serializable。所以序列化这个对象应该不是问题。我整个晚上都在处理这个问题。希望任何人都可以帮助我摆脱这个。

【问题讨论】:

  • 您要传输什么类型的公钥? RSA?顺便说一句,确保您通过安全连接传输它们 - 否则这些密钥不应该被信任。
  • 抱歉,它是公共 RSA 密钥。该频道将被保存以供传输。
  • 您不使用 SSL 的某些原因?还是发送证书而不只是其公钥?
  • 是的,有一些原因。该程序用于学术用途,应尽可能传输公钥。
  • 如果您知道算法将是 rsa,您可以调用 RSAPublicKey 的 getPublicModulus() 和 getPublicExponent() 方法并将它们写入 OutputStream(序列化或作为文本)。在接收方,您可以使用 KeyFactory 和 RSAPublicKeySpec 实例化密钥。

标签: java sockets exception serialization


【解决方案1】:

您的问题中没有足够的代码来完全诊断 - 但这里有一些观察结果。

这段代码看起来很可疑:

if(client.getInputStream().available() > 2)
com = is.readLine();

大概您有一个缓冲阅读器is 包装客户端输入流。如果 if 语句不正确会发生什么 - 您跳过阅读该行?现在该行文本仍在管道中,并将传递给您的 keyIn.readObject 方法。这可能会导致损坏错误。

我建议只删除整个 if 行。 readLine() 无论如何都会阻塞,所以不需要检查。

另外,你确定AdminServerCommand.NODE_REGISTER.writeToPrintWriter(pw); 只发送一行文本,换行后绝对没有字符吗?

但是-我认为您在这里遇到了更大的问题。这种在 Java 对象序列化和手动文本读取/写入之间来回切换的设计只是一场等待发生的灾难。如果要使用对象序列化,请独占使用它。您可以交替发送一个 String 对象,然后发送一个 Key 对象,并且您的流不会因为您发送的换行过多或两个换行符而损坏。

例如: ObjectOutputStream outO = new ObjectOutputStream(out);

    String command = "whatever";
    outO.writeObject(command);
    outO.writeObject(cyper.getPublicKey());
    outO.flush();

那么在服务器端,总是使用readObject,知道第一个是命令,第二个是键。

【讨论】:

    猜你喜欢
    • 2011-12-12
    • 2019-08-14
    • 2021-08-14
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    相关资源
    最近更新 更多