Java套接字通信-传输加密数据



我必须基本上设计一个echo程序。服务器中的何处侦听端口。接收它得到的内容。对其进行解密、显示、加密所接收的内容并将其发送回客户端。我向套接字发送数据的方式有问题。因为我认为加密文本可能包含各种垃圾,因此将其作为字符串发送是不可行的,因此我想将其作为字节发送。我的服务器程序无法读取客户端发送给它的加密文本。

有人能纠正我的错误吗?

服务器代码

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import java.net.*;
public class socket_server_simple {
    public static byte[] getBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);
        // Get the size of the file
        long length = file.length();
        // You cannot create an array using a long type.
        // It needs to be an int type.
        // Before converting to an int type, check
        // to ensure that file is not larger than Integer.MAX_VALUE.
        if (length > Integer.MAX_VALUE) {
        // File is too large
        }
        // Create the byte array to hold the data
        byte[] bytes = new byte[(int)length];
        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }
        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+file.getName());
        }
        // Close the input stream and return bytes
        is.close();
        return bytes;
    }
    public static String asHex (byte buf[]) {
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;
        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10)
                strbuf.append("0");
            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strbuf.toString();
    }
    public static String aes_run(String message, String username, int mode) throws Exception
    {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(256); // 192 and 256 bits may not be available
        // Generate the secret key specs.
        SecretKey skey = kgen.generateKey();
        String keyfilepath=new String(username+".key");
        File keyfile = new File(keyfilepath);
        byte[] raw = getBytesFromFile(keyfile);
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        System.out.println("Key file foundnn");
           // Instantiate the cipher
        byte[] encdecres;
        String encdecresstr=new String();
        Cipher cipher = Cipher.getInstance("AES");
        if(mode==0)
            {
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                encdecres= cipher.doFinal(message.getBytes());
                encdecresstr= new String(encdecres);
            }
            else if(mode==1)
            {
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);
                encdecres = cipher.doFinal(message.getBytes());
                encdecresstr= new String(encdecres);
            }
            return encdecresstr;
    }
    public static void main(String args[]) throws Exception
    {
        char[] buffer = new char[3000];
        String message;
        String username;
        String orgmsg;
        char encryptedmsg[] = new char[400];
            if(args.length<1)
                {
                    System.out.println("Usage: java socket_server_simple <port_num>");
                    System.exit(1);
                }
        ServerSocket serversock = new ServerSocket(Integer.parseInt(args[0])); //can be any port
        System.out.println("Socket Instantiated!n");
        Socket  connsock = serversock.accept();
        InputStreamReader instr =  new InputStreamReader(connsock.getInputStream());
        DataOutputStream outstr = new DataOutputStream(connsock.getOutputStream());
        System.out.println("Streams Instantiated!n");  
        BufferedReader in = new BufferedReader(instr);
        System.out.println("Server is up! Waiting for usernamenn");
        username = in.readLine();
        System.out.println("Username recieved: "+username+"nn");              
        while(true)
        {
            System.out.println("Waiting for messagen");
            //message=in.readLine();
            //int len = instr.readLine(encryptedmsg,0,300);
            int len = in.read(buffer, 0,3000);  
            String strEnc = new String(buffer,0,len);
            //message = in.readLine();          
            //System.out.println("len: "+len);
            System.out.println("Encrypted msg received: "+strEnc);
            /*for(int i=0; i<400; i++)
            {
                System.out.print((encryptedmsg[i]));
            }*/
            //String strEnc = new String(encryptedmsg);
            //System.out.println(strEnc);
            orgmsg=aes_run(strEnc,username,1);          
            System.out.println("Decrypting message : "+orgmsg+"n");
            //orgmsg=aes_run(encryptedmsg.toString(),username,1);
            //System.out.println("Encrypted Message :"+asHex(message.getBytes())+"nPlain text"+orgmsg+"n");
                //messagereturn = ""You send me ->" +message.toUpperCase() + ""n";
                //outstr.writeBytes(messagereturn);
        }
    }
}

客户代码

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;
import java.net.*;
public class socket_client_simple {
    public static byte[] getBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);
        // Get the size of the file
        long length = file.length();
        // You cannot create an array using a long type.
        // It needs to be an int type.
        // Before converting to an int type, check
        // to ensure that file is not larger than Integer.MAX_VALUE.
        if (length > Integer.MAX_VALUE) {
        // File is too large
        }
        // Create the byte array to hold the data
        byte[] bytes = new byte[(int)length];
        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }
        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+file.getName());
        }
        // Close the input stream and return bytes
        is.close();
        return bytes;
    }
    public static String asHex (byte buf[]) {
        StringBuffer strbuf = new StringBuffer(buf.length * 2);
        int i;
        for (i = 0; i < buf.length; i++) {
            if (((int) buf[i] & 0xff) < 0x10)
                strbuf.append("0");
            strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
        }
        return strbuf.toString();
    }
    public static String aes_run(String message, String username, int mode) throws Exception
    {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(256); // 192 and 256 bits may not be available
        // Generate the secret key specs.
        SecretKey skey = kgen.generateKey();
        String keyfilepath=new String(username+".key");
        File keyfile = new File(keyfilepath);
        byte[] raw = getBytesFromFile(keyfile);
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        System.out.println("Key file foundnn");
           // Instantiate the cipher
        byte[] encdecres;
        String encdecresstr= new String();
        Cipher cipher = Cipher.getInstance("AES");
            if(mode==0)
            {
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                encdecres= cipher.doFinal(message.getBytes());
                encdecresstr= new String(encdecres);
            }
            else if(mode==1)
            {
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);
                encdecres = cipher.doFinal(message.getBytes());
                encdecresstr= new String(encdecres);
            }
            return encdecresstr;
    }   
    public static void main(String[] args) throws Exception
    {
        String message,encrypted;
        String  returnmessage;
        String username=args[2];
        BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
        if(args.length<3)
        {
            System.out.println("Usage: java socket_client_simple <ip_address> <Port_num> <username>");
            System.exit(1);
        }
        Socket  mysock = new Socket("localhost",Integer.parseInt(args[1])); 
        System.out.println("Socket Instantiatednn");      
        DataOutputStream out = new DataOutputStream( mysock.getOutputStream());
        BufferedReader in = new BufferedReader(new InputStreamReader(mysock.getInputStream()));
        out.writeBytes(username+"n");
        do 
        {
            System.out.println("Enter Message: ");
            message=keyboard.readLine();
            System.out.println("Sending messagen");
            //System.out.println(aes_run(message.getBytes(),username,0) + "n");
            encrypted = aes_run(message,username,0);
            System.out.println("length: "+encrypted.length());
            out.write(encrypted + "n");
            System.out.println("message sent: "+encrypted );
            System.out.println("Waiting for replynn");
            returnmessage = in.readLine();
            System.out.println("Server replied: " + aes_run(returnmessage,username,1));
        }while(!message.equals("bye"));
        mysock.close();
    }
}

事实证明,问题在于将数据作为加密的字节流发送。我已经在java中使用Object流解决了这个问题,并完成了我必须完成的任务

谢谢你的帮助。

最新更新