java 密钥工厂 desede_20145212 实验五《Java网络编程》
20145212 實驗五《Java網(wǎng)絡(luò)編程》
一、實驗內(nèi)容1.運行下載的TCP代碼,結(jié)對進行,一人服務(wù)器,一人客戶端;
2.利用加解密代碼包,編譯運行代碼,一人加密,一人解密;
3.集成代碼,一人加密后通過TCP發(fā)送;
4.結(jié)對伙伴:20145223楊夢云,我負責(zé)服務(wù)端,她負責(zé)客戶端。
注:加密使用AES或者DES/AES或者DES加密密鑰key并發(fā)送,使用服務(wù)器的公鑰加密/公鑰算法使用RSA或DH/檢驗發(fā)送信息的完整性使用MD5或者SHA3;
5.完成Blog。
二、實驗步驟1.學(xué)習(xí)TCP
根據(jù)如下程序,體會TCP含義。
服務(wù)器端:
package chapter9;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTest
{
public static final int PORT = 8081;
public static void main(String[] args) throws IOException
{
ServerSocket s = new ServerSocket(PORT);
System.out.println("Started:"+s);
try
{
Socket socket = s.accept();
try
{
System.out.println("Connection accepted:"+socket);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
while(true)
{
String str=in.readLine();
if(str.equals("END"))
break;
System.out.print("Echoing:"+str);
out.println(str);
}
}
finally
{
System.out.println("closing...");
socket.close();
}
}
finally
{
s.close();
}
}
}
客戶端:
package chapter9;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;;
public class ClientTest
{
public static void main(String[] args) throws IOException
{
InetAddress addr = InetAddress.getByName("192.168.1.35");
System.out.println("addr ="+addr);
Socket socket = new Socket(addr,ServerTest.PORT);
try
{
System.out.println("socket="+socket);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
for(int i =0;i<0;i++)
{
out.println("howdy"+i);
String str = in.readLine();
System.out.println(str);
}
out.println("END");
}
finally
{
System.out.println("closing...");
socket.close();
}
}
}
2.信息安全傳送:
發(fā)送方A——————>接收方B
A加密時,用B的公鑰
B解密時,用B的私鑰
·發(fā)送方A對信息(明文)采用DES密鑰加密,使用RSA加密前面的DES密鑰信息,最終將混合信息進行傳遞。同時用hash函數(shù)將明文進行用作驗證。
·接收方B接收到信息后,用RSA解密DES密鑰信息,再用RSA解密獲取到的密鑰信息解密密文信息,最終就可以得到我們要的信息(明文)。用hash函數(shù)對解出的明文進行驗證。
3.運行加解密包中的程序
·運行DES加密代碼
import java.io.*;
import javax.crypto.*;
public class Skey_DES{
public static void main(String args[]) throws Exception{
KeyGenerator kg=KeyGenerator.getInstance("DESede");
kg.init(168);
SecretKey k=kg.generateKey( );
FileOutputStream f=new FileOutputStream("key1.dat");
ObjectOutputStream b=new ObjectOutputStream(f);
b.writeObject(k);
}
}
import java.io.*;
import java.security.*;
public class Skey_kb{
public static void main(String args[]) throws Exception{
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject( );
byte[ ] kb=k.getEncoded( );
FileOutputStream f2=new FileOutputStream("keykb1.dat");
f2.write(kb);
// 打印密鑰編碼中的內(nèi)容
for(int i=0;i
System.out.print(kb[i]+",");
}
}
}
String keyString=”abcd”;
byte[]keyData=keyString.getBytes();
secretKey myDeskey=new SecretKeySpec(keyData,”DES”);
·獲取密鑰生成器
KeyGenerator kg=KeyGenerator.getInstance("DESede");
·Java中KeyGenerator類中提供了創(chuàng)建對稱密鑰的方法。Java中的類一般使用new操作符通過構(gòu)造器創(chuàng)建對象,但KeyGenerator類不是這樣,它預(yù)定義了一個靜態(tài)方法getInstance(),通過它獲得KeyGenerator類型的對象。這種類成為工廠類或工廠。
·方法getInstance( )的參數(shù)為字符串類型,指定加密算法的名稱。可以是 “Blowfish”、“DES”、“DESede”、“HmacMD5”或“HmacSHA1”等。這些算法都可以實現(xiàn)加密,這里我們不關(guān)心這些算法的細節(jié),只要知道其使用上的特點即可。
·初始化密鑰生成器
該步驟一般指定密鑰的長度。如果該步驟省略的話,會根據(jù)算法自動使用默認的密鑰長度。指定長度時,若第一步密鑰生成器使用的是“DES”算法,則密鑰長度必須是56位;若是“DESede”,則可以是112或168位,其中112位有效;若是“AES”,可以是128, 192或256位。
·生成密鑰SecretKey k=kg.generateKey( );
使用第一步獲得的KeyGenerator類型的對象中g(shù)enerateKey( )方法可以獲得密鑰。其類型為SecretKey類型,可用于以后的加密和解密。
·通過對象序列化方式將密鑰保存在文件中
FileOutputStream f=new FileOutputStream("key1.dat");
ObjectOutputStream b=new ObjectOutputStream(f); b.writeObject(k);
·ObjectOutputStream類中提供的writeObject方法可以將對象序列化,以流的方式進行處理。這里將文件輸出流作為參數(shù)傳遞給ObjectOutputStream類的構(gòu)造器,這樣創(chuàng)建好的密鑰將保存在文件key1.data中。
4.最終,服務(wù)器端代碼如下:
package javaapplication40;
import java.net.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class MyServer {
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
ServerSocket sc = null;
ServerSocket sc1 = null;
Socket socket=null;
Socket socket1=null;
try {
sc= new ServerSocket(4431);//創(chuàng)建服務(wù)器套接字
sc1= new ServerSocket(4430);//創(chuàng)建服務(wù)器套接字
System.out.println("端口號:" + sc.getLocalPort());
System.out.println("服務(wù)器1已經(jīng)啟動...");
System.out.println("端口號:" + sc1.getLocalPort());
System.out.println("服務(wù)器2已經(jīng)啟動...");
socket = sc.accept(); //等待客戶端連接
System.out.println("已經(jīng)建立連接");
socket1 = sc1.accept(); //等待客戶端連接
System.out.println("已經(jīng)建立1連接");
//獲得網(wǎng)絡(luò)輸入流對象的引用
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader in1 = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
獲得網(wǎng)絡(luò)輸出流對象的引用
System.out.print("已接收\n");
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
String aline=in.readLine();//讀取客戶端傳送來的數(shù)據(jù)
String aline1=in1.readLine();
System.out.print("寫入文件中...\n");
byte [] bytes = aline.getBytes("GB2312");
byte [] bytes1 = aline1.getBytes("GB2312");
aline = new String(bytes, "GB2312");
aline1 = new String(bytes1, "GB2312");
FileOutputStream s=new FileOutputStream("key1.dat");
s.write(bytes);
FileOutputStream s1=new FileOutputStream("SEnc.dat");
s1.write(bytes1);
System.out.print("已寫入文件\n");
//生成解密密鑰
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject( );
byte[ ] kb=k.getEncoded( );
FileOutputStream f2=new FileOutputStream("keykb1.dat");
f2.write(kb);
System.out.print("生成解密密鑰\n");
// 打印密鑰編碼中的內(nèi)容
for(int i=0;i
// System.out.print(kb[i]+",");
}
//解密
FileInputStream a=new FileInputStream("SEnc.dat");
int num=a.available();
byte[ ] ctext=new byte[num];
a.read(ctext);
FileInputStream f1=new FileInputStream("keykb1.dat");
int num2=f1.available();
byte[ ] keykb=new byte[num2];
f1.read(keykb);
SecretKeySpec e=new SecretKeySpec(keykb,"DESede");
Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.DECRYPT_MODE, k);
byte []ptext=cp.doFinal(ctext);
String p=new String(ptext,"GB2312");
System.out.print("解密中...\n");
System.out.println(p);
//返回
System.out.println("從客戶端接收到信息為:"+p); //通過網(wǎng)絡(luò)輸出流返回結(jié)果給客戶端
out.println(p);
out.close();
in.close();
sc.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
三、實驗中遇到的問題及解決方案出現(xiàn)java.net.BindException:Address already in use: JVM_Bind
通過百度原因,我們知道這是因為端口已經(jīng)被占用,只需要找一個沒有被占用的端口就能解決這個問題。
兩臺電腦無法聯(lián)通
1.在實驗室時我們起初是從網(wǎng)絡(luò)上搜ip出來的地址,然后顯示連接超時。之后用在命令行中用ipconfig查看地址,找到自己的IPv4地址,但是換上之后還是失敗了——連接超時。
2.我們認為可能是兩臺電腦沒有在同一個網(wǎng)絡(luò)里而不發(fā)鏈接成功,嘗試著用一臺電腦連接網(wǎng)絡(luò)然后wifi給另一臺電腦使用,然后再次連接兩臺電腦,終于連通成功了。
連接成功后出現(xiàn)java.net.SocketException: Connection reset
該異常在客戶端和服務(wù)器端均有可能發(fā)生,引起該異常的原因有兩個,第一個就是如果一端的Socket被關(guān)閉(或主動關(guān)閉或者因為異常退出而引起的關(guān)閉),另一端仍發(fā)送數(shù)據(jù),發(fā)送的第一個數(shù)據(jù)包引發(fā)該異常(Connect reset by peer)。另一個是一端退出,但退出時并未關(guān)閉該連接,另一端如果在從連接中讀數(shù)據(jù)則拋出該異常(Connection reset)。簡單的說就是在連接斷開后的讀和寫操作引起的。
實驗中出現(xiàn)了問題是因為代碼在運行到讀寫數(shù)據(jù)的時候鏈接已經(jīng)失效,通過修改,最終成功。
服務(wù)端:
客戶端:
## PSP(Personal Software Process)時間步驟耗時百分比
需求分析20min8.3%
設(shè)計60min25.0%
代碼實現(xiàn)80min33.3%
測試40min16.7%
分析總結(jié)40min16.7%
總結(jié)
以上是生活随笔為你收集整理的java 密钥工厂 desede_20145212 实验五《Java网络编程》的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上海欢乐谷内有啥吃的
- 下一篇: java人工洗牌窗口程序_求解,用JAV