参考文章:http://blog.csdn.net/chw1989/article/details/7584995 实现JSEE双向验证SSL
http://blog.csdn.net/xiaotanyu13/article/details/7928904 证书生成
http://blog.chinaunix.net/uid-17102734-id-2830223.html java keytools用法详解
D:\用户目录\Desktop\SSL\new\ 任意目录 E:\desktop\bcprov-jdk15on-146.jar bcprov-jdk15on-146.jar 的路径 -validity 365指证书有效期,如果证书过期,就得读者自己去重新生成4个证书
客户端
生成键值对bks
keytool -genkey -alias clientkey -keystore D:\用户目录\Desktop\SSL\new\kclient.bks -validity 365 -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
密钥 111111 公钥222222
生成客户端证书命令
keytool -exportcert -alias clientkey -keystore D:\用户目录\Desktop\SSL\new\kclient.bks -file D:\用户目录\Desktop\SSL\new\client.cer -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
导入服务器端证书命令
keytool -import -alias serverkey -file D:\用户目录\Desktop\SSL\new\server.cer -keystore D:\用户目录\Desktop\SSL\new\tclient.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
服务端
生成键值对jks
keytool -genkey -alias serverkey -keystore D:\用户目录\Desktop\SSL\new\kserver.keystore -validity 365
密钥123456 公钥654321
生成服务端证书命令
keytool -export -alias serverkey -keystore D:\用户目录\Desktop\SSL\new\kserver.keystore -file D:\用户目录\Desktop\SSL\new\server.cer
导入客户端证书命令
keytool -import -alias clientkey -file D:\用户目录\Desktop\SSL\new\client.cer -keystore D:\用户目录\Desktop\SSL\new\tserver.keystore
Android只支持BKS
手机端实现简单的Socket通讯,见如下代码
package com.yzj.testssl;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.http.client.methods.HttpGet;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Context mContext;
private Button mBt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext=getApplicationContext();
mBt=(Button)findViewById(R.id.bt);
init();
mBt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
sendMsg();
}
}).start();
}
});
}
private void init(){
}
private void sendMsg(){
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory keyManager = KeyManagerFactory.getInstance("X509");
TrustManagerFactory trustManager = TrustManagerFactory.getInstance("X509");
//取得BKS密库实例
KeyStore kks= KeyStore.getInstance("BKS");
KeyStore tks = KeyStore.getInstance("BKS");
//加客户端载证书和私钥,通过读取资源文件的方式读取密钥和信任证书
InputStream kksin=null;
InputStream tksin=null;
try {
kksin=getAssets().open("kclient.bks");
tksin=getAssets().open("tclient.bks");
kks.load(kksin,"111111".toCharArray());
tks.load(tksin,"333333".toCharArray());
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(null!=kksin){
try {
kksin.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(null!=tksin){
try {
tksin.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//初始化密钥管理器
keyManager.init(kks,"222222".toCharArray());
trustManager.init(tks);
//初始化SSLContext
sslContext.init(keyManager.getKeyManagers(),trustManager.getTrustManagers(),null);
Socket clientsocket=sslContext.getSocketFactory().createSocket();
InetSocketAddress remoteAddr=new InetSocketAddress("113.88.57.161",7779);
clientsocket.connect(remoteAddr, 5000);
try {
InputStream input = clientsocket.getInputStream();
OutputStream output = clientsocket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(input);
BufferedOutputStream bos = new BufferedOutputStream(output);
bos.write("1234567890".getBytes());
bos.flush();
byte[] buffer = new byte[20];
bis.read(buffer);
Log.w("zjc","read:"+new String(buffer));
clientsocket.close();
} catch (IOException e) {
e.printStackTrace();
Log.w("zjc","IOException:"+e.getMessage());
}
}catch(Exception e){
e.printStackTrace();
Log.d("zjc","fail excepiton:"+e.getMessage());
}
}
}
服务端代码:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManagerFactory;
public class Server implements Runnable{
private static final int DEFAULT_PORT=7779;
private static final String SERVER_KEY_STORE_PASSWORD = "123456";
private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "444444";
private SSLServerSocket serverSocket;
public static void main(String[] args) {
Server server = new Server();
server.init();
Thread thread = new Thread(server);
thread.start();
}
public synchronized void start() {
if (serverSocket == null) {
System.out.println("ERROR");
return;
}
while (true) {
try {
Socket s = serverSocket.accept();
InputStream input = s.getInputStream();
OutputStream output = s.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(input);
BufferedOutputStream bos = new BufferedOutputStream(output);
byte[] buffer = new byte[20];
bis.read(buffer);
System.out.println("------receive:--------"+new String(buffer).toString());
bos.write("yes".getBytes());
bos.flush();
s.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
}
public void init() {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore tks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("src/kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray());
tks.load(new FileInputStream("src/tserver.keystore"), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
kmf.init(ks, "654321".toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);
serverSocket.setNeedClientAuth(true);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
public void run() {
// TODO Auto-generated method stub
start();
}
}
结果如图:
手机客户端点击helloworld按钮后
服务端显示
如此,就完成了服务端和客户端之间的基于身份认证的交互。
client采用kclient.keystore中的clientkey私钥进行数据加密,发送给server。
server采用tserver.keystore中的client.crt证书(包含了clientkey的公钥)对数据解密,如果解密成功,证明消息来自client,进行逻辑处理。
server采用kserver.keystore中的serverkey私钥进行数据加密,发送给client。
client采用tclient.keystore中的server.crt证书(包含了serverkey的公钥)对数据解密,如果解密成功,证明消息来自server,进行逻辑处理。
如果过程中,解密失败,那么证明消息来源错误。不进行逻辑处理。这样就完成了双向的身份认证。
代码及jar地址:http://download.csdn.net/detail/z157794218/8664027
P12格式转换命令
客户端
生成键值对bks
keytool -genkey -alias clientkey -keystore D:\用户目录\Desktop\SSL\new\kclient.bks -validity 365 -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
密钥 111111 公钥222222
生成客户端证书命令
keytool -exportcert -alias clientkey -keystore D:\用户目录\Desktop\SSL\new\kclient.bks -file D:\用户目录\Desktop\SSL\new\client.cer -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
导入服务器端证书命令
keytool -import -alias serverkey -file D:\用户目录\Desktop\SSL\new\server.cer -keystore D:\用户目录\Desktop\SSL\new\tclient.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
keytool -import -alias server -file E:\ssl\server.cer -keystore E:\ssl\server.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar
keytool -export -alias client -keystore E:\ssl\client.p12 -file E:\ssl\client.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar
keytool -exportcert -alias client -keystore E:\ssl\client.p12 -file E:\ssl\client.cer -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar
keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\client.keystore -deststoretype jks -deststorepass 123456
keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype jks -srcstorepass 123456 -destkeystore E:\ssl\client.keystore -deststoretype jks -deststorepass 123456
从P12导入BKS
keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\client.bks -deststoretype bks -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar -deststorepass 123456
服务端
生成键值对jks
keytool -genkey -alias serverkey -keystore D:\用户目录\Desktop\SSL\new\kserver.keystore -validity 365
密钥123456 公钥654321
生成服务端证书命令(
keytool -export -alias serverkey -keystore D:\用户目录\Desktop\SSL\new\kserver.keystore -file D:\用户目录\Desktop\SSL\new\server.cer
导入客户端证书命令
keytool -import -alias clientkey -file D:\用户目录\Desktop\SSL\new\client.cer -keystore D:\用户目录\Desktop\SSL\new\tserver.keystore
一、keytool -validity 365 -genkey -v -alias server -keyalg RSA -keystore E:\ssl\server.keystore -dname "CN=127.0.0.1,OU=icesoft,O=icesoft,L=Haidian,ST=Beijing,c=cn" -storepass 123456 -keypass 123456
二、keytool -validity 365 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore E:\ssl\client.p12 -dname "CN=client,OU=icesoft,O=icesoft,L=Haidian,ST=Beijing,c=cn" -storepass 123456 -keypass 123456
三、keytool -export -v -alias client -keystore E:\ssl\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file E:\ssl\client.cer
四、keytool -export -v -alias server -keystore E:\ssl\server.keystore -storepass 123456 -rfc -file E:\ssl\server.cer
五、keytool -import -v -alias server -file E:\ssl\server.cer -keystore E:\ssl\client.truststore -storepass 123456
六、keytool -import -v -alias client -file E:\ssl\client.cer -keystore E:\ssl\server.keystore -storepass 123456
keytool -export -v -alias client -keystore E:\ssl\client.p12
客户端
生成键值对bks
keytool -genkey -alias clientkey -keystore D:\用户目录\Desktop\SSL\new\kclient.bks -validity 365 -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
密钥 111111 公钥222222
生成客户端证书命令
keytool -exportcert -alias clientkey -keystore D:\用户目录\Desktop\SSL\new\kclient.bks -file D:\用户目录\Desktop\SSL\new\client.cer -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
导入服务器端证书命令
keytool -import -alias server -file E:\ssl\server.cer -keystore E:\ssl\server.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar
keytool -import -alias serverkey -file D:\用户目录\Desktop\SSL\new\server.cer -keystore D:\用户目录\Desktop\SSL\new\tclient.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
keytool -exportcert -alias client -keystore E:\ssl\client.p12 -file E:\ssl\client.cer -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar
keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\client.keystore -deststoretype jks -deststorepass 123456
keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype jks -srcstorepass 123456 -destkeystore E:\ssl\client.keystore -deststoretype jks -deststorepass 123456
从P12导入BKS
keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\client.bks -deststoretype bks -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar -deststorepass 123456
服务端
生成键值对jks
keytool -genkey -alias serverkey -keystore D:\用户目录\Desktop\SSL\new\kserver.keystore -validity 365
密钥123456 公钥654321
生成服务端证书命令(
keytool -export -alias serverkey -keystore D:\用户目录\Desktop\SSL\new\kserver.keystore -file D:\用户目录\Desktop\SSL\new\server.cer
导入客户端证书命令
keytool -import -alias clientkey -file D:\用户目录\Desktop\SSL\new\client.cer -keystore D:\用户目录\Desktop\SSL\new\tserver.keystore
p12转BKS
keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\client.bks -deststoretype bks -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar -deststorepass 123456
keytool -importkeystore -v -srckeystore E:\ssl\E\ssl-192.168.1.196\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\E\ssl-192.168.1.196\client.bks -deststoretype bks -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar -deststorepass 123456
keytool -import -alias server -file E:\ssl\E\ssl-192.168.1.196\server.cer -keystore E:\ssl\E\ssl-192.168.1.196\server.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar
keytool -export -v -alias client -keystore E:\ssl\client.p12
一、keytool -validity 365 -genkey -v -alias server -keyalg RSA -keystore E:\ssl\server.keystore -dname "CN=127.0.0.1,OU=icesoft,O=icesoft,L=Haidian,ST=Beijing,c=cn" -storepass 123456 -keypass 123456
二、keytool -validity 365 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore E:\ssl\client.p12 -dname "CN=client,OU=icesoft,O=icesoft,L=Haidian,ST=Beijing,c=cn" -storepass 123456 -keypass 123456
三、keytool -export -v -alias client -keystore E:\ssl\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file E:\ssl\client.cer
四、keytool -export -v -alias server -keystore E:\ssl\server.keystore -storepass 123456 -rfc -file E:\ssl\server.cer
五、keytool -import -v -alias server -file E:\ssl\server.cer -keystore E:\ssl\client.truststore -storepass 123456
六、keytool -import -v -alias client -file E:\ssl\client.cer -keystore E:\ssl\server.keystore -storepass 123456
七、keytool -import -alias serverkey -file D:\用户目录\Desktop\SSL\new\server.cer -keystore D:\用户目录\Desktop\SSL\new\server.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\desktop\bcprov-jdk15on-146.jar
八、keytool -importkeystore -v -srckeystore E:\ssl\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\client.bks -deststoretype bks -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\工作\朱\tools\bcprov-jdk15on-146.jar -deststorepass 123456
keytool -import -alias serverkey -file E:\ssl\100300\server.cer -keystore E:\ssl\100300\server.bks -storetype BKS -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\ssl\bcprov-jdk15on-146.jar
keytool -importkeystore -v -srckeystore E:\ssl\100300\client.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore E:\ssl\100300\client.bks -deststoretype bks -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath E:\ssl\bcprov-jdk15on-146.jar -deststorepass 123456