首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > Java > 用OpenSSL与JAVA(JSSE)通信
【标  题】:用OpenSSL与JAVA(JSSE)通信
【关键字】:OpenSSL,JAVA,JSSE
【来  源】:http://www.blogjava.net/alwayscy/archive/2006/12/03/85161.html

用OpenSSL与JAVA(JSSE)通信

用OpenSSL与JAVA(JSSE)通信 - 我爱佳娃 - BlogJava
随笔-7  评论-0  文章-0  trackbacks-0

概念
JAVA使用keystore文件来存储所有KEY,keystore文件可以存放多个KEY,访问它需要密码。
下面我介绍下如何将用OpenSSL做自签名的证书一文中介绍的OpenSSL产生的KEY与JAVA的KEY转换后使用,从而达到JAVA与OpenSSL通信的目的。


用OpenSSL生成CA根证书,即(P1,V1)
此步骤参见用OpenSSL做自签名的证书一文


在JAVA环境下生成自己的KEY,即(P2,V2)

keytool -genkey -alias clientapp -keystore mycerts

注意:这里会提示输入访问keystore的密码,以及组织、城市、省份,一定要与CA根证书的一致,否则不能被CA签名。


从keystore中导出public key,即P2

keytool -keystore mycerts -certreq -alias clientapp -file clientapp.crs


用CA根证书为这个public key进行签名,即用V1给P2加密

openssl ca -out clientapp.pem -config ./openssl.cnf -infiles?clientapp.crs
?

转换PEM到DER格式

openssl x509 -in clientapp.pem -out clientapp.der -outform DER


导入CA证书,即P1

keytool -keystore mycerts -alias systemca -import -file cacert.pem


导入用户证书,即被V1加密过的P2

keytool -keystore mycerts -alias clientapp -import -file clientapp.der

注意:这里一定要先导入CA证书再导入用户证书,否则会报错。

现在我们就生成了JAVA服务器使用的所有KEY了,在程序中将mycerts这个keystore导入就可以了。
如果客户端是使用OpenSSL的程序,那么用CA证书cacert.pem就能正常通信了,如果也是JAVA程序,那么我们需要将CA证书也转换成keystore:

keytool -import -keystore clikeystore -import -trustcacerts -file cacert.pem

生成的clikeystore供JAVA客户端使用,就能通信。


再附上SVR和CLI的JAVA程序,我已经用上面的KEY都测试通过:
SVR端:

import ?java.io. * ;
import ?java.net. * ;
import ?com.sun.net.ssl.KeyManagerFactory;
import ?com.sun.net.ssl.KeyManager;
import ?com.sun.net.ssl.TrustManagerFactory;
import ?com.sun.net.ssl.TrustManager;
import ?com.sun.net.ssl.SSLContext;
import ?javax.net.ServerSocketFactory;
import ?java.security.KeyStore;

public ? class ?svr? implements ?Runnable {
??
??
public ? static ? final ? int ?PORT? = ? 5555 ;
??
public ? static ? final ?String?HOST? = ? " localhost " ;
??
public ? static ? final ?String?QUESTION? = ? " Knock,?knock. " ;
??
public ? static ? final ?String?ANSWER? = ? " Who's?there? " ;

??
// ?The?new?constants?that?are?used?during?setup.
?? public ? static ? final ?String?KEYSTORE_FILE? = ? " mycerts " ; // "server_keystore";
?? public ? static ? final ?String?ALGORITHM? = ? " sunx509 " ;
??
public ? static ? final ?String?PASSWORD? = ? " churchillobjects " ;
??
??
public ? static ? void ?main(String[]?args) {
????
new ?Thread( new ?svr()).start();
??}

??
??
public ? void ?run() {
????ServerSocket?ss?
= ? null ;
????
try ? {

??????
// ?Local?references?used?for?clarity.?Their?presence
??????
// ?here?is?part?of?the?reason?we?need?to?import
??????
// ?so?many?classes.
??????KeyManagerFactory?kmf;
??????KeyManager[]?km;
??????KeyStore?ks;
??????TrustManagerFactory?tmf;
??????TrustManager[]?tm;
??????SSLContext?sslc;
??????
??????
// ?Create?a?keystore?that?will?read?the?JKS?(Java?KeyStore)
??????
// ?file?format?which?was?created?by?the?keytool?utility.
??????ks? = ?KeyStore.getInstance( " JKS " );
??????
??????
// ?Load?the?keystore?object?with?the?binary?keystore?file?and
??????
// ?a?byte?array?representing?its?password.
??????ks.load( new ?FileInputStream(KEYSTORE_FILE),?PASSWORD.toCharArray());
??????
??????
// ?Gives?us?a?factory?for?key?managers?that?will?let
??????
// ?us?handle?the?asymetric?keys?we?created?earlier.
??????kmf? = ?KeyManagerFactory.getInstance(ALGORITHM);

??????
// ?Initialize?the?key?manager?factory?with?the?keystore?object,
??????
// ?again?using?the?same?password?for?security?since?it?is?going?to
??????
// ?access?the?private?key.
??????kmf.init(ks,?PASSWORD.toCharArray());
??????
??????
// ?Now?we?can?get?the?key?managers?from?the?factory,?since?it?knows
??????
// ?what?type?we?are?using?now.
??????km? = ?kmf.getKeyManagers();
??????
??????
// ?Next,?create?a?trust?manager?factory?using?the?same?algorithm.
??????
// ?This?is?to?avoid?using?the?certificates?in?cacerts?that
??????
// ?represent?an?authentication?security?risk.
??????tmf? = ?TrustManagerFactory.getInstance(ALGORITHM);
??????
??????
// ?then?initialize?it?with?the?keystore?object.?This?time?we?don't
??????
// ?need?the?keystore?password.?This?is?because?trusted?certificates
??????
// ?are?not?a?sensitive?element?in?the?keystore,?unlike?the
??????
// ?private?keys.
??????tmf.init(ks);
??????
??????
// ?Once?that's?initialized,?get?the?trust?managers?from?the?factory.
??????tm? = ?tmf.getTrustManagers();
??????
??????
// ?Almost?done,?we?need?a?context?object?that?will?get?our
??????
// ?server?socket?factory.?We?specify?TLS?to?indicate?that?we?will
??????
// ?need?a?server?socket?factory?that?supports?SSL.
??????sslc? = ?SSLContext.getInstance( " TLS " );
??????
??????
// ?Initialize?the?context?object?with?the?key?managers?and?trust
??????
// ?managers?we?got?earlier.?The?third?parameter?is?an?optional
??????
// ?SecureRandom?object.?By?passing?in?null,?we?are?letting?the
??????
// ?context?object?create?its?own.
??????sslc.init(km,?tm,? null );
??????
??????
// ?Finally,?we?get?the?ordinary-looking?server?socket?factory
??????
// ?from?the?context?object.
??????ServerSocketFactory?ssf? = ?sslc.getServerSocketFactory();
??????
??????
// ?From?the?factory,?we?simply?ask?for?an?ordinary-looking
??????
// ?server?socket?on?the?port?we?wish.
??????ss? = ?ssf.createServerSocket(PORT);

??????listen(ss);
????}

????
catch (Exception?e) {
??????e.printStackTrace();
????}

????
finally {
??????
if (ss != null ) {
????????
try {
??????????ss.close();
????????}

????????
catch (IOException?e) {
??????????
// ?oh,?well
????????}

??????}

??????System.exit(
0 );
????}

??}

??
??
static ? void ?listen(ServerSocket?ss)? throws ?Exception {
????System.out.println(
" Ready?for?connections. " );
????
while ( true ) {
??????Socket?s?
= ?ss.accept();
??????BufferedWriter?bw?
= ? new ?BufferedWriter(
????????
new ?OutputStreamWriter(s.getOutputStream()));
??????BufferedReader?br?
= ? new ?BufferedReader(
????????
new ?InputStreamReader(s.getInputStream()));
??????String?q?
= ?br.readLine();
??????
if ( ! QUESTION.equals(q)) {
????????
throw ? new ?RuntimeException( " Wrong?question:?\ "" ?+?q?+? " \ "" );
??????}

??????System.out.println(
" Question:?\ "" ?+?q?+? " \ "" );
??????bw.write(ANSWER
+ " \n " );
??????bw.flush();
??????s.close();
????}

??}

}


CLI端程序:

import ?java.io. * ;
import ?java.net. * ;
import ?com.sun.net.ssl.KeyManagerFactory;
import ?com.sun.net.ssl.TrustManagerFactory;
import ?com.sun.net.ssl.SSLContext;
import ?java.security.KeyStore;
import ?javax.net.SocketFactory;

public ? class ?cli? implements ?Runnable {
??
??
public ? static ? final ? int ?PORT? = ? 5555 ;
??
public ? static ? final ?String?HOST? = ? " localhost " ;
??
public ? static ? final ?String?KEYSTORE_FILE? = ? " clikeystore " ; // "client_keystore";
?? public ? static ? final ?String?ALGORITHM? = ? " sunx509 " ;
??
public ? static ? final ?String?PASSWORD? = ? " churchillobjects " ;
??
public ? static ? final ?String?QUESTION? = ? " Knock,?knock. " ;
??
public ? static ? final ?String?ANSWER? = ? " Who's?there? " ;
??
??
public ? static ? void ?main(String[]?args) {
????
new ?Thread( new ?cli()).start();
??}

??
??
public ? void ?run() {
????Socket?socket?
= ? null ;
????
try {
??????KeyManagerFactory?kmf;
??????KeyStore?ks;
??????TrustManagerFactory?tmf;
??????SSLContext?sslc;

??????kmf?
= ?KeyManagerFactory.getInstance(ALGORITHM);
??????ks?
= ?KeyStore.getInstance(? " JKS " ?);
??????ks.load(
new ?FileInputStream(KEYSTORE_FILE),?PASSWORD.toCharArray());
??????kmf.init(ks,?PASSWORD.toCharArray());
??????tmf?
= ?TrustManagerFactory.getInstance(ALGORITHM);
??????tmf.init(ks);
??????sslc?
= ?SSLContext.getInstance( " TLS " );
??????sslc.init(kmf.getKeyManagers(),?tmf.getTrustManagers(),?
null );

??????
// ?The?process?is?different?from?here?on?the?client.?Instead?of
??????
// ?getting?a?ServerSocketFactory,?we?ask?for?a?SocketFactory?from
??????
// ?the?SSL?context.
??????SocketFactory?sf? = ?sslc.getSocketFactory();

??????
// ?Then?we?get?the?socket?from?the?factory?and?treat?it
??????
// ?as?if?it?were?a?standard?(plain)?socket.
??????socket? = ?sf.createSocket(HOST,?PORT);
????
??????doQuery(socket);
????}

????
catch (Exception?e) {
??????e.printStackTrace();
????}

????
finally {
??????
if (socket != null ) {
????????
try {
??????????socket.close();
????????}

????????
catch (IOException?e) {
??????????
// ?oh,?well
????????}

??????}

??????System.exit(
0 );
????}

??}


??
private ? void ?doQuery(Socket?s)? throws ?Exception {
????BufferedWriter?bw?
= ? new ?BufferedWriter( new ?OutputStreamWriter(s.getOutputStream()));
????BufferedReader?br?
= ? new ?BufferedReader( new ?InputStreamReader(s.getInputStream()));
????bw.write(QUESTION
+ " \n " );
????bw.flush();
????String?response?
= ?br.readLine();
????
if ( ! ANSWER.equals(response)) {
??????
throw ? new ?RuntimeException( " Wrong?answer:?\ "" ?+?response?+? " \ "" );
????}

????System.out.println(
" Got?the?right?answer:?\ "" ?+?response?+? " \ "" );
??}

}




以上方法主要参考了如下两个网页:

http://www.churchillobjects.com/c/11201g.html

http://mark.foster.cc/kb/openssl-keytool.html

posted on 2006-12-03 12:36 我爱佳娃 阅读(176) 评论(0)  编辑 收藏 引用 收藏至365Key 所属分类: SSL
【相关评论】
没有相关评论
【发表评论】
姓名:
邮件:
随机码*
评论*
      
|  首 页  |  版权声明  |  联系我们   |  网站地图  |
CopyRight © 2004-2007 软讯网络 All Rigths Reserved.