【问题标题】:Generating a DES key and passing it through the socket in Java生成 DES 密钥并通过 Java 中的套接字传递它
【发布时间】:2017-08-04 09:06:32
【问题描述】:

有人可以帮我找出我非常简单的程序中的问题吗?

在服务器上输出消息时,我希望看到通过网络发送的相同消息,但我没有收到。

这是我的客户端代码:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import javax.crypto.*;

public class CipherClient
{
    public static void main(String[] args) throws Exception 
    {
        String message = "The quick brown fox jumps over the lazy dog.";
        String host = "localhost";
        int port = 7999;
        Socket s = new Socket(host, port);

        // -Generate a DES key.
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        generator.init(new SecureRandom());
        Key key = generator.generateKey();

        // -Store it in a file.
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        out.writeObject(key);
        out.close();

        // -Use the key to encrypt the message above and send it over socket s to the server.   
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        CipherOutputStream cipherOut = new CipherOutputStream(s.getOutputStream(), cipher);
        System.out.println(message.getBytes().length);
        cipherOut.write(message.getBytes());
    }
}

这是我的服务器代码:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;

public class CipherServer
{
    public static void main(String[] args) throws Exception 
    {
        int port = 7999;
        ServerSocket server = new ServerSocket(port);
        Socket s = server.accept();

        // -Read the key from the file generated by the client.
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        Key key = (Key)in.readObject();
        System.out.println(key.getClass().getName());
        in.close();

        // -Use the key to decrypt the incoming message from socket s.      
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        CipherInputStream cipherIn = new CipherInputStream(s.getInputStream(), cipher);
        byte[] stringInBytes = new byte[44];
        cipherIn.read(stringInBytes);
        String string = new String(stringInBytes);

        // -Print out the decrypt String to see if it matches the orignal message.
        System.out.println(string);
    }
}

服务器端的控制台输出:

javax.crypto.spec.SecretKeySpec
}#ùÂ?°ô0íÿ| r|XÌ\?ñw޳{Í@nŠ?

客户端的控制台输出:

44

这是我的客户新代码:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;

public class CipherClient
{
    public static void main(String[] args) throws Exception 
    {
        // -Generate a DES key.
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        generator.init(new SecureRandom());
        Key key = generator.generateKey();

        // -Store it in a file.
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        out.writeObject(key);
        out.close();

        // -Connect to a server.
        String message = "The quick brown fox jumps over the lazy dog.";
        String host = "localhost";
        int port = 7999;
        Socket s = new Socket(host, port);

        // -Use the key to encrypt the message above and send it over socket s to the server.   
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = cipher.doFinal(message.getBytes());
        DataOutputStream dOut = new DataOutputStream(s.getOutputStream());
        dOut.writeInt(encVal.length); // write length of the message
        dOut.write(encVal);           // write the message
    }
}

这是我的服务器新代码:

package encryption;

import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;

public class CipherServer
{
    public static void main(String[] args) throws Exception 
    {
        int port = 7999;
        ServerSocket server = new ServerSocket(port);
        Socket s = server.accept();

        // -Read the key from the file generated by the client.
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        Key key = (Key)in.readObject();
        in.close();

        // -Use the key to decrypt the incoming message from socket s.    
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);

        DataInputStream dIn = new DataInputStream(s.getInputStream());
        int length = dIn.readInt();                    // read length of incoming message
        if(length>0) 
        {
            byte[] messageInBytes = new byte[length];
            dIn.readFully(messageInBytes, 0, messageInBytes.length); // read the message

            // -Print out the decrypt String to see if it matches the orignal message.
            System.out.println(new String(cipher.doFinal(messageInBytes)));
        }
    }
}

这是我在服务器端遇到的错误:

Exception in thread "main" java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.io.DataInputStream.readInt(Unknown Source)
    at encryption.CipherServer.main(CipherServer.java:26)

并且客户端没有错误。

【问题讨论】:

  • I would like to see the same message that was sent over the network, but I am not getting one. 所以你什么也没看到?没有堆栈跟踪,没有消息?你试过不用钥匙吗?
  • @Nathan,已更新。
  • @Nathan,我仍然无法找出问题所在。请帮帮我。

标签: java sockets security encryption stream


【解决方案1】:

我认为您的客户端和服务器之间存在“竞争”来写入和读取您的密钥文件。至少当我运行你的代码时它对我有用。

尝试在创建套接字之前将密钥生成和写入密钥文件。这样,当您的客户端创建它的套接字时,服务器会接受它,当它转到文件时,它确实会得到一个有效的文件。

它对我有用,除了写入文件位之外,它与您的代码几乎没有区别。

客户:

public class CipherClient
{
    public static void main(String[] args) throws Exception 
    {
        // -Generate a DES key.
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        generator.init(new SecureRandom());
        Key key = generator.generateKey();

        // -Store it in a file.
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        out.writeObject(key);
        out.close();

        String message = "The quick brown fox jumps over the lazy dog.";
        System.out.println("Message converted from Bytes = " + new String(message.getBytes()));
        System.out.println("Length = " + message.getBytes().length);

        String host = "localhost";
        int port = 7999;
        Socket s = new Socket(host, port);

        // -Use the key to encrypt the message above and send it over socket s to the server.   
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        CipherOutputStream cipherOut = new CipherOutputStream(s.getOutputStream(), cipher);
        cipherOut.write(message.getBytes());
        cipherOut.close();
        s.close();
    }
}

还有服务器:

public class CipherServer
{
    public static void main(String[] args) throws Exception 
    {
        int port = 7999;
        ServerSocket server = new ServerSocket(port);
        Socket s = server.accept();

        // -Read the key from the file generated by the client.
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        Key key = (Key)in.readObject();
        in.close();

        // -Use the key to decrypt the incoming message from socket s.      
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        CipherInputStream cipherIn = new CipherInputStream(s.getInputStream(), cipher);

        byte[] array = new byte[44];
        cipherIn.read(array);
        cipherIn.close();
        s.close();

        String message = new String(array);
        System.out.println(message);
    }
}

【讨论】:

  • 让我试一试,非常感谢您的关注。
  • 仍然得到相同的输出?
  • 这是我在服务器端得到的:线程“main”中的 javax.crypto.spec.SecretKeySpec 异常 java.net.SocketException:连接在 java.net.SocketInputStream.read 处重置(未知来源) 在 java.net.SocketInputStream.read(Unknown Source) 在 java.net.SocketInputStream.read(Unknown Source) 在 javax.crypto.CipherInputStream.getMoreData(CipherInputStream.java:114) 在 javax.crypto.CipherInputStream.read(CipherInputStream .java:239) 在 javax.crypto.CipherInputStream.read(CipherInputStream.java:215) 在 encryption.CipherServer.main(CipherServer.java:27)
  • 你先运行服务器了吗?
  • 看问题。我稍微调整了一下。
猜你喜欢
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多