2012-02-27 112 views
2

我必须基本上设计一个回声程序。服务器在哪里监听端口。收到它得到的东西。解密它,显示它,加密接收到的内容并将其发送回客户端。我正在将数据发送到套接字的方式出错。因为我认为加密的文本可能包含各种垃圾,因此将它作为字符串发送是不可行的,因此我想将它作为字节发送。 我的服务器程序无法读取客户端发送给它的加密文本。Java套接字通信 - 传输加密数据

有人可以纠正我吗?

服务器代码

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 found\n\n"); 
      // 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 username\n\n"); 
     username = in.readLine(); 
     System.out.println("Username recieved: "+username+"\n\n");    
     while(true) 
     { 
      System.out.println("Waiting for message\n"); 
      //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 found\n\n"); 
      // 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 Instantiated\n\n");  
     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 message\n"); 

      //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 reply\n\n"); 
      returnmessage = in.readLine(); 
      System.out.println("Server replied: " + aes_run(returnmessage,username,1)); 
     }while(!message.equals("bye")); 
     mysock.close(); 
    } 

} 
+0

除非您使用流密码,否则您需要设计一个协议来承载加密块。 – 2012-02-27 00:18:38

+0

流密码可能不是一个坏主意,至少你不会受到填充oracle攻击的影响。目前Hitesh正在使用特别不安全的ECB模式加密(在所有编码/解码问题和完全没有任何作用的代码中)。 – 2012-02-27 01:38:29

+0

Hitesh,能否请您删除您的应用程序中并非严格要求的所有部分?这就像试图在干草堆中找到一堆针。 – 2012-02-27 01:39:47

回答

0

原来问题就出在发送数据,这是加密的字节流。我已经在java中使用Object流解决了这个问题,并完成了我所需要的。

感谢您的帮助。