zoukankan      html  css  js  c++  java
  • 实验五Java网络编程及安全——20135337朱荟潼

    实验五 Java网络编程及安全

    结对伙伴:20135317韩玉琪(负责服务器方)http://www.cnblogs.com/hyq20135317/p/4567241.html

    实验内容

    1.掌握Socket程序的编写;

    2.掌握密码技术的使用;

    3.设计安全

    实验步骤

    1.信息安全传送:             

       
       

    发送方A——————>接收方B

    A加密时,用B的公钥

    B解密时,用B的私钥

      发送方A对信息(明文)采用DES密钥加密,使用RSA加密前面的DES密钥信息,最终将混合信息进行传递。同时用hash函数将明文进行用作验证。

        接收方B接收到信息后,用RSA解密DES密钥信息,再用RSA解密获取到的密钥信息解密密文信息,最终就可以得到我们要的信息(明文)。用hash函数对解出的明文进行验证,与发送过来的hash值相等,验证通过。

    实验代码

    import java.net.*;

    import java.io.*;

    import java.security.*;

    import javax.crypto.*;

    import javax.crypto.spec.*;

    import java.security.spec.*;

    import javax.crypto.interfaces.*;

    import java.security.interfaces.*;

    import java.math.*;

    public class Client {

        public static void main(String args[]) throws Exception{

          try {

                KeyGenerator kg=KeyGenerator.getInstance("DESede");//Java中KeyGenerator类中提供了创建对称密钥的方法;

                kg.init(168); //初始化密钥生成器,指定密钥的长度。        SecretKey k=kg.generateKey( );//生成密钥,使用第一步获得的KeyGenerator类型的对象中generateKey( )方法可以获得密钥。其类型为SecretKey类型,可用于以后的加密和解密。

                byte[] ptext2=k.getEncoded();// 获取主要编码格式,将返回的编码放在byte类型的数组中。

              

                Socket socket = new Socket("192.168.88.1",8080);//创建连接到服务器的8080端口

                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));//从服务器端获得输入流

                PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true); //获得向服务器端输出数据的输出

                BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); //从键盘上输入信息

               

                //服务器端RSA的公钥对DES的密钥进行加密

                FileInputStream f3=new FileInputStream("Skey_RSA_pub.dat");//将文件中保存的对象读取出来以便使用

                ObjectInputStream b2=new ObjectInputStream(f3);

                RSAPublicKey  pub_key=(RSAPublicKey)b2.readObject( );//生成公钥

                BigInteger e=pub_key.getPublicExponent();

                BigInteger n=pub_key.getModulus();//模

                System.out.println("e= "+e);

                System.out.println("n= "+n);//(n,e)是公钥

                BigInteger m=new BigInteger(ptext2);

                BigInteger c=m.modPow(e,n);

                System.out.println("c= "+c);

                String cs=c.toString( );

                out.println(cs);  //传送到服务器

               

                System.out.print("请输入待发送的数据:"); 

                String s=stdin.readLine(); //从键盘读入要发送的发信息

                Cipher cp=Cipher.getInstance("DESede");//获取Cipher实例 密码器

                cp.init(Cipher.ENCRYPT_MODE, k);//初始化cipher ENCRYPT_MODE表示加密DECRYPT_MODE解密 , k是密钥

                byte by[]=s.getBytes("UTF8");//获取字符串的utf8字节码

                byte miby[]=cp.doFinal(by);//加密后的字节码

                String str=parseByte2HexStr(miby);//获取密文字符串

                out.println(str);  //传送到服务器

               

                //将客户端的明文哈希值传送给密文

                String x=s;

                MessageDigest m2=MessageDigest.getInstance("MD5");//通过其静态方法getInstance( )生成MessageDigest对象。

                m2.update(x.getBytes( ));//x为需要计算的字符串,用getBytes( )方法生成字符串数组。

                byte ss[ ]=m2.digest( );//计算的结果通过字节类型的数组返回。

                String result="";//将计算结果ss转换为字符串

                for (int i=0; i<ss.length; i++){

                result+=Integer.toHexString((0x000000ff & ss[i]) | 0xffffff00).substring(6);

                }

                System.out.println(result);

                out.println(result);

           

                str=in.readLine();//读取结果

                System.out.println( "从服务器接收到的结果为:"+str);

            }

            catch (Exception e) {

                System.out.println(e);

            }

         }

         

        //将二进制转换成16进制

         public static String parseByte2HexStr(byte buf[]) { 

            StringBuffer sb = new StringBuffer(); 

            for (int i = 0; i < buf.length; i++) { 

                String hex = Integer.toHexString(buf[i] & 0xFF); 

                if (hex.length() == 1) { 

                    hex = '0' + hex; 

                } 

                sb.append(hex.toUpperCase()); 

            } 

            return sb.toString(); 

        } 

       

         //将16进制转换为二进制

        public static byte[] parseHexStr2Byte(String hexStr) { 

            if (hexStr.length() < 1) 

                return null; 

            byte[] result = new byte[hexStr.length()/2]; 

            for (int i = 0;i< hexStr.length()/2; i++) { 

                int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16); 

                int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16); 

                result[i] = (byte) (high * 16 + low); 

            } 

            return result; 

        } 

    }

     连接结果截图

    实验总结

    1. 两台电脑一直无法联通

    在实验室时我们起初是从网络上搜ip出来的地址,然后显示连接超时。之后用在命令行中用ipconfig查看地址,找到自己的IPv4地址,但是换上之后还是失败了——连接超时。

    我们认为可能是两台电脑没有在同一个网络里而不发链接成功,尝试着用一台电脑连接网络然后wifi给另一台电脑使用,然后再次连接两台电脑,终于连通成功了。

    2. 显示连通了之后,客户端向服务器发送消息,但是显示有异常。将端口换了一个变成端口8080之后,再次连接发送消息,成功。

    3.在读老师给的代码时,看懂还是有一定的难度的,并且要与密码学的知识联系起来,于是我从网络上看了几个“牛人”的博客,他们解释的很详细,能让读者比较容易的了解。

     

     

  • 相关阅读:
    linux查看CPU和内存信息
    linux yum命令详解
    查看文件中关键字前后几行的内容
    vue.js+web storm安装及第一个vue.js
    android GPS: code should explicitly check to see if permission is available
    ASP.NET MVC Identity 使用自己的SQL Server数据库
    阿里云服务器,tomcat启动,一直卡在At least one JAR was scanned for TLDs yet contained no TLDs就不动了
    ASP.NET MVC4 MVC 当前上下文中不存在名称“Scripts”
    python 将windows字体中的汉字生成图片的方法
    Java android DES+Base64加密解密
  • 原文地址:https://www.cnblogs.com/zzzz5/p/4567392.html
Copyright © 2011-2022 走看看