安全套接字编程示例
安全套接字(Security Socket Layer)是在Socket的基础上加入加密机制而产生的.应用在安全性要求比较的场合.比如VPN(Virtual privacy network)中,可以实现点对点的隧道通信机制.在SVN(一个应用比较广泛的开源的版本控制软件)中,如果你只希望你代码通过网络checkin/checkout的时候不被恶意的读取,则可以启用SSL,这样传输过程中的源代码是以密文的形式传输的,即使被网络上的恶意截获,没有加密的密码,仍然可以保证您的源代码的安全性.下面是SSL握手过程:
(1)客户发送消息到服务器,要求SLL连接,并且提供它所支持的加密解密算法列表
(2)服务器通过发送包含公钥的证书,并发送建议(基于客户机和服务器的能力,应该施用哪个密码组)来响应
(3)客户施用收到的证书和可信任的CA对服务器进行验证,客户使用服务器的公钥对一条称为预制作秘密的数据加密,并发送到服务器
(4)服务器使用自己的私钥解密预制作秘密
(5)通过将预制作秘密作为由SSL定义的算法的输入,客户机和服务器都产生会话秘钥.现在会话秘匙是客户机和服务器共享的秘密,其他人不知道.
(6)客户机和服务器交换信息表示握手结束.会话中以后的消息都使用秘钥加密,并且包括了MAC(Message Digest Code),以便检测任何对数据的篡改.
java 提供了对SSL的支持,所以下面是用java写的服务器和客户代码
/*SecureServer.java*/
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import javax.crypto.*;
import java.security.*;
import java.util.StringTokenizer;
public class SecureServer
{
private int port;
static final int DEFAULT_PORT=8189;
static final String KEYSTORE="jpatkeystore.ks";
static final String TRUSTSTORE="jpattruststore.ks";
static final String STOREPASSWD="changeit";
static final String ALIASPASSWD="changeit";
SecureServer(int port)
{
this.port=port;
}
public void run()
{
try
{
KeyStore ks=KeyStore.getInstance("JCEKS");
ks.load(new FileInputStream(KEYSTORE),STOREPASSWD.toCharArray());
KeyStore ts=KeyStore.getInstance("JCEKS");
ts.load(new FileInputStream(TRUSTSTORE),STOREPASSWD.toCharArray());
KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509");
kmf.init(ks,ALIASPASSWD.toCharArray());
TrustManagerFactory tmf=TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
SSLContext sslContext=SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(),tmf.getTrustManagers(),null);
SSLServerSocketFactory sslServerFactory=sslContext.getServerSocketFactory();
SSLServerSocket sss=(SSLServerSocket)sslServerFactory.createServerSocket(port);
sss.setEnabledCipherSuites(sss.getSupportedCipherSuites());
SSLSocket incoming=(SSLSocket)sss.accept();
BufferedReader in=new BufferedReader(InputStreamReader(incoming.getInputStream()));
PrintWriter out=new PrintWriter(incoming.getOutputStream(),true);
String str;
while(!(str=in.readLine()).equals(" "))
{
double result=0;
StringTokenizer st=new StringTokenizer(str);
try
{
while(st.hasMoreTokens())
{
Double d=new Double(st.nextToken());
result+=d.doubleValue();
}
out.println("The result is"+result);
}
catch(NumberFormatException nfe)
{
out.println("invalid input number!");
}
}
incoming.close();
}
catch(Exception x)
{
System.out.println(x);
x.printStackTrace();
}
}
public static void main(String[] args)
{
int port=DEFAULT_PORT;
if(args.length>0)
{
port=Integer.parseInt(args[0]);
}
SecureServer addServer=new SecureServer(port);
addServer.run();
}
}
/*SecureClient.java*/
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import java.security.KeyStore;
public class SecureClient
{
private InetAddress host;
private int port;
static final int DEFAULT_PORT=8189;
static final String KEYSTORE="jpatkeystore.ks";
static final String TRUSTSTORE="jpattruststore.ks";
static final String STOREPASSWD="changeit";
static final String ALIASPASSWD="changeit";
SecureClient(InetAddress host,int port)
{
this.host=host;
this.port=port;
}
public void run()
{
try
{
KeyStore ks=KeyStore.getInstance("JCEKS");
ks.load(new FileInputStream(KEYSTORE),STOREPASSWD.toCharArray());
KeyStore ts=KeyStore.getInstance("JCEKS");
ts.load(new FileInputStream(TRUSTSTORE),STOREPASSWD.toCharArray());
KeyManagerFactory kmf=KeyManagerFactory.getInstance("SunX509");
kmf.init(ks,ALIASPASSWD.toCharArray());
TrustManagerFactory tmf=TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
SSLContext sslContext=SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(),tmf.getTrustManagers(),null);
SSLSocketFactory sslFact=sslContext.getSocketFactory();
SSLSocket client=(SSLSocket)sslFact.createSocket(host,port);
client.setEnabledCipherSuites(client.getSupportedCipherSuites());
BufferedReader socketIn=new BufferedReader(InputStreamReader(client.getInputStream()));
PrintWriter socketOut=new PrintWriter(client.getOutputStream(),true);
String numbers="1.2 3.4 5.6";
System.out.println("Adding the numbers"+numbers+"together securely");
socketOut.println(numbers);
System.out.println(socketIn.readLine());
socketOut.println(" ");
}
catch(Exception x)
{
System.out.println(x);
x.printStackTrace();
}
}
public static void main(String[] args)
{
try
{
InetAddress host=InetAddress.getLocalHost();
int port=DEFAULT_PORT;
if(args.length>0)
{
port=Integer.parseInt(args[0]);
}
if(args.length>1)
{
host=InetAddress.getByName(args[1]);
}
SecureClient addClient=new SecureClient(host,port);
addClient.run();
}
catch(UnknownHostException uhx)
{
System.out.println(uhx);
uhx.printStackTrace();
}
}
}