Topic: [转载]Java Secure Socket Extension (JSSE)探索

  Print this page

1.[转载]Java Secure Socket Extension (JSSE)探索 Copy to clipboard
Posted by: feiggle
Posted on: 2003-04-21 18:01

摘自(東海大學資訊工程與科學系/沈勃甫),希望对想了解ssl与https的朋友
有所帮助!

簡介

在網際網路的快速發展下,上網人數也隨著快速地增加,使用者可以透過網際網路方便存取各種的服務,但在這公共網路中,在上面傳送的資料很容易被不肖使用者取得,如:個人隱私資料、通行密碼及信用卡卡號…等,所以在確保私密性的資料能夠安全的送達,都需經過加密,以確保安全,所以資料加密在網際網路中更是個重要的課題之一。

在Java中有許多與網路安全相關套件,如:Java Cryptography Extension(JCE)、Java Secure Socket Extension(JSSE)及Java Authentication and Authorization Service(JAAS),另外還有新發展出套件Java GSS-API及Java Certification Path API。本文介紹如何使用JSSE套件開發出安全的網路程式,JSSE可以讓程式開發人員發展出一個於伺服端與客戶端之間溝通資料安全的架構,完全由Java開發完成,它的功能包括可以實作SSL 及TLS傳輸協定,含伺服器與用戶的鑑別、資料加密及訊息的真確性等。

接下來將先簡單介紹SSL,在介紹JSSE的特性及其套件功能,最後是範例程式說明及結論。

Secure Sockets Layer(SSL)協定簡介

Secure Socket Layer(SSL)是由Netscape公司在1994年所提出一種網路安全的協定,使用資料加密的技術保障在網路的資料真確性,將它定義於應用層(Application Layer)及傳輸層(TCP)之間,提供資料加密、伺服端鑑別、訊息真確性及客戶端鑑別給TCP/IP做傳送。本文重點在於如何將SSL運用於Java技術上,故在此不對SSL多做說明。

JSSE套件簡述

JSSE在J2SDK v1.2及v.13不是必備的API,而在J2SDK中已經把它成為基本的API。現在我們將為您介紹在J2SDK1.4中JSSE的API功能,javax.net、javax.net.ssl和javax.security.cert,特色及優點如下。

● 它是完全由Java開發完成。

● 支援 SSL v2.0及v3.0,TLS v1.0。

● 提供能夠發展出安全通道(secure channels)的類別,如:SSLSocket 及 SSLServerSocket。

●伺服端與客戶端的鑑別(authentication),如:SSL交握(Handshake)協定。

●支援私密鑰匙及認證機構(Certificate Authority)。

● RSA 加密演算法。

● HTTPS支援:如可在HTTPS下取得HTML文件。

提供多種加密演算法,包含:

加密演算法種類 Key Length(bits)

RSA public key 2048 (authentication), 2048 (key agreement)

RC4 128

DES 64 (56 effective)

Triple DES 192 (112 effective)

Diffie-Hellman public key 1024

DSA public key 2048

SunJSSE Provider

Provider 是指提供某種演算法的廠商,如A公司遵循JDK 規格,提供了DSA 演算法,則A公司即是一個provider,在J2SDK1.4中JSSE內定的Provider為「SunJSSE」。Providers 提供的演算法函式庫稱為”engine algorithms”,簡稱engines 。而JSSE中所提供engines類別有SSLContext、KeyManagerFactory 及 TrustManagerFactory。除此之外,尚有在Java Security標準的engines類別。下面將分類依不同的類別所提供的演算法及協定:

Engines類別名稱 演算法/協定

KeyFactory RSA

KeyPairGenerator RSA

KeyStore PKCS12

Signature MD2withRSA、MD5withRSA、SHA1withRSA

KeyManagerFactory SunX509

TrustManagerFactory SunX509

SSLContext SSL、SSLv3、TLS、TLSv1

JSSE範例程式

我們現在實作出一個架構於TLS之上的Echo Server來當作範例說明,首先使用<JAVAHOME>/bin/keytool的執行檔建構出一個憑證檔案 (truststore),此檔案提供給伺服端與客戶端方便讓兩端做鑑別使用,下面利用keytool產生出以RSA演算法的一個「testkeys」的憑證檔案。執行時,它會要求輸入密碼、姓名、單位、組織…..等,相關資料。

keytool -genkey -alias duke -keystore testkeys -keyalg rsa

首先說明在伺服端上的撰寫方式,先定義provider為” com.sun.net.ssl.internal.ssl.Provider”。

String provider = "com.sun.net.ssl.internal.ssl.Provider";

java.security.Security.addProvider((Provider)Class.forName(provider).newInstance());

接著設定KeyStore物件,使用load(InputStream stream ,char[] password),將之前由keytool所產生的檔案及設定的密碼傳入即可。然後將KeyManagerFactory物件使用getInstance(String algorithm),這則是使用SunJSSE所提供的”SunX509”,再用init()設定原先的keystore及密碼。建立SSLContext物件時,需使用getInstance(String protocol)方法來產生,在此所使用的協定為”TLS”,使用init()將先前的KeyManager產生SSLServerSocketFactory。

KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("testkeys"),"test1234".toCharArray());

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

kmf.init(keystore, "test1234".toCharArray());

SSLContext sslc = SSLContext.getInstance("TLS");

sslc.init(kmf.getKeyManagers(), null, null);

SSLServerSocketFactory ssf = sslc.getServerSocketFactory();

使用上面所產生出的SSLServerSocketFactory物件,取得SSLServerSocket,當客戶端連線時則會產生SSLSocket物件,並取得OutputStream及InputStream即可與客戶端溝通。

SSLServerSocket sslServer=(SSLServerSocket)ssf.createServerSocket(port);

sslServer.setEnabledCipherSuites(sslServer.getSupportedCipherSuites());
SSLSocket sslSocket=(SSLSocket)sslServer.accept();
OutputStream out = sslSocket.getOutputStream();
InputStream in = sslSocket.getInputStream();

完成伺服端之後,現在開始撰寫客戶端的程式,與伺服端相較之下,顯得精簡很多,首先與伺服端一樣先設定provider,設定java.lang.system的屬性使用setProperty(),產生SSLSocketFactory物件再建構出SSLSocket,設定伺服端位址及port,即可與伺服端溝通。

java.security.Security.addProvider((Provider)Class.forName(provider).newInstance());
System.setProperty("javax.net.ssl.trustStore", "testkeys");

SSLSocketFactory sslFactory=(SSLSocketFactory)SSLSocketFactory.getDefault();

SSLSocket s=(SSLSocket)sslFactory.createSocket(host,port);

OutputStream out=s.getOutputStream();

InputStream in=s.getInputStream();

2.Re:[转载]Java Secure Socket Extension (JSSE)探索 [Re: feiggle] Copy to clipboard
Posted by: floater
Posted on: 2003-04-21 23:53

With JSSE, you can do this:

URL url = new URL("https://....");

for https. The hook is:

System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

This should work under "normal condition", namely you use commercial server side certs. Otherwise, if you use your own certs(nobody CA), you need to work on the key store a little bit.

3.Re:[转载]Java Secure Socket Extension (JSSE)探索 [Re: feiggle] Copy to clipboard
Posted by: feiggle
Posted on: 2003-04-22 11:30

in fact,there are two concepts, Keystores and Truststores
JSSE introduces the notion of a truststore, which is a database that holds certificates. In fact, a truststore has exactly the same format as a keystore; both are administered with keytool, and both are represented programmatically as instances of the KeyStore class. The difference between a keystore and a truststore is more a matter of function than of programming construct, keystores are used to provide credentials, while truststores are used to verify credentials. Servers use keystores to obtain the certificates they present to the clients; clients use truststores to obtain root certificates in order to verify the servers' certificates.

4.Re:[转载]Java Secure Socket Extension (JSSE)探索 [Re: feiggle] Copy to clipboard
Posted by: floater
Posted on: 2003-04-23 00:43

Good point!


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923