安全性是當前程序設計工作中的一個重要方面
由於應用程序在網絡上呈分散分布
因而每個部分都需要保護自己的基礎框架部分
而這在以前是內置到主應用程序中的
隨著這些情況的變化
作為基礎的 JavaTM
平台發行版也進行了不斷演變
並在 J
SE
發行版 中並入了越來越多的功能
從而提供了一個可以執行移動代碼的安全環境
在最新的
發行版中
您會發現在安全體系結構中實現了許多增強功能
以前單獨提供的幾個功能現已成為核心 API 集中的一部分
其中包括通過 Java Cryptography Extension (JCE) 支持加密和解密
通過 Java Secure Socket Extension (JSSE) 實現的對安全套接字層 (SSL) 和傳輸層安全性 (TLS) 協議的支持
以及通過使用 Java Authentication and Authorization Service (JAAS) 實現的對基於用戶的身份鑒定和訪問控制的支持
除了包含這些以前的可選軟件包以外
您還會發現新增了通過使用 Java Certification Path API實現的對生成和檢驗證書鏈的支持以及對 Java GSS
API 和 JAAS 下的 Kerberos V
機制的支持
此外
還改進了安全策略管理工具 policytool
並添加了對動態載入安全策略的支持
以下各節將介紹並深入檢查所有這些功能
Java Cryptography Extension
在 Java Cryptography Extension (JCE) 庫中
您會發現對加密
解密
密鑰協議
信息鑒定代碼 (MAC)以及其它加密法服務的支持
由於某些國家/地區的進口控制限制
Java
SDK
發行版附帶的JCE 轄區政策文件允許使用強大但有限的加密法
而在其它國家/地區(占大多數)
則可以使用這些文件的
完全
版本
從而充分利用其強大的加密法而不受任何限制
您可以下載此版本
並使用此不受限制的版本替換隨 Java
SDK
發行版提供的字符串加密法版本
JCE 庫可以將無格式文本轉換為密文或反向轉換
在 javax
crypto 軟件包中可以找到該庫
這裡的密鑰類是 Cipher
它決定了用於加密和解密的加密算法
借助 CipherOutputStream 和 CipherInputStream 類所提供的方便
這些 I/O 過濾流可以完成加密或解密任務
當您向流中寫入或從中讀取時
適當的流便傳遞給了構造函數
然後它們便可以完成各自的任務
您唯一需要關心的是密鑰的管理和使用什麼樣的 Cipher 算法
為演示 JCE API
以下程序將對一系列對象進行加密
然後再解密
該示例使用數據加密標准 (DES) 作為加密算法
有關所支持的算法的完整列表
請參閱 Java Cryptography Extension (JCE) Reference Guide
代碼樣例
通過加密和解密一系列對象演示 JCE API
import java
io
*;
import javax
crypto
*;
import javax
crypto
spec
*;
import java
security
*;
import java
security
spec
*;
import java
util
*;
public class EncryptTest {
public static void main(String args[]) {
File desFile = new File(
out
des
);
// 創建要加密的數據
Map map = new TreeMap(System
getProperties());
int number = map
size();
try {
// 創建密鑰
KeyGenerator kg = KeyGenerator
getInstance(
DES
);
SecretKey secretKey = kg
generateKey();
// 創建密碼
Cipher desCipher =
Cipher
getInstance(
DES/ECB/PKCS
Padding
);
desCipher
init(Cipher
ENCRYPT_MODE
secretKey);
// 創建流
FileOutputStream fos = new FileOutputStream(desFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
CipherOutputStream cos = new CipherOutputStream(bos
desCipher);
ObjectOutputStream oos = new ObjectOutputStream(cos);
// 寫對象
oos
writeObject(map);
oos
writeInt(number);
oos
flush();
oos
close();
// 更改密碼模式
desCipher
init(Cipher
DECRYPT_MODE
secretKey);
// 創建流
FileInputStream fis = new FileInputStream(desFile);
BufferedInputStream bis = new BufferedInputStream(fis);
CipherInputStream cis = new CipherInputStream(bis
desCipher);
ObjectInputStream ois = new ObjectInputStream(cis);
// 讀對象
Map map
= (Map)ois
readObject();
int number
= ois
readInt();
ois
close();
// 將讀回的內容與原始內容相比較
if (map
equals(map
) && (map
size() == number
)) {
System
out
println(
Everything read back out okay
);
} else {
System
out
println(
Problems during
encryption/decryption process
);
}
} catch (NoSuchPaddingException e) {
System
err
println(
Padding problem:
+ e);
} catch (NoSuchAlgorithmException e) {
System
err
println(
Invalid algorithm:
+ e);
} catch (InvalidKeyException e) {
System
err
println(
Invalid key:
+ e);
} catch (IOException e) {
System
err
println(
I/O Problem:
+ e);
} catch (ClassNotFoundException e) {
System
err
println(
Class loading Problem:
+ e);
} finally {
if (desFile
exists()) {
desFile
delete();
}
}
}
}
Java Secure Socket Extension
接下來將介紹 Java Secure Socket Extension (JSSE) 庫
從中您會發現對使用安全套接字層 (SSL) 和傳輸層安全性 (TLS) 協議進行通信的支持
與對特定的本地數據結構執行操作的 JCE 不同
JSEE 使用了另一種提取方法
從而對網絡套接字通信應用加密/解密技術
它添加了服務器鑒定
信息完整性和可選的客戶機鑒定
大多數人把 SSL 和 TLS 視為安全的 HTTP 協議
並稱為 HTTPS
JSSE 庫位於 和
ssl 軟件包中
要使用 SSL 進行套接字通信
您必須借助一個輔助機制
而不是從其構造函數中創建 Socket
首先從 SSLSocketFactory 獲取一個 SocketFactory
然後再從該工廠創建 Socket
當建立了安全連接後
只需寫入套接字或從中讀取
即可對數據進行加密或解密
在此機制之上可以建立其它高層協議
如 HTTPS
SSL(亦即 HTTPS)允許在客戶機和服務器之間交換加密的通信
當 SSL 客戶機開始與 SSL 服務器的對話後
服務器會向客戶機發送回一個 X
證書要求進行鑒定
然後客戶機將檢查該證書的有效性
假設服務器通過檢驗
客戶機將預先生成一個安全密鑰
然後使用證書中的服務器的公共密鑰對其進行加密
並將加密後的密鑰發送回服務器
根據此事先掌握的密鑰
客戶機和服務器將為會話生成一個主密鑰
經過一番基本的握手程序後
加密交換便可以開始了
JSSE 庫對您隱藏了 SSL 協議的這些內部工作
您只需象對待普通套接字一樣使用從工廠創建的 Socket
以下示例演示了如何使用 JSSE 庫
它使用 SSL 讀取了一個 Web 頁
即使發送到服務器的 GET 命令說明要使用 HTTP協議
但因為 Socket 是從 SSLSocketFactory 創建的
所以仍然使用了 SSL 與服務器進行通信
以發送頁面請求並接收響應
代碼樣例
通過從端口
(即 HTTPS 端口)讀取 Web 頁
演示如何使用 JSSE 庫
import java
io
*;
import
*;
import
*;
import
ssl
*;
public class JSSE {
static final int HTTPS_PORT =
;
public static void main(String args[]) {
String hostname;
// 獲得主機名或使用 VeriSign
if (args
length ==
) {
hostname =
;
} else {
hostname = args[
];
}
try {
// 獲得套接字工廠
SocketFactory factory = SSLSocketFactory
getDefault();
// 從工廠獲得套接字
Socket s = factory
createSocket(hostname
HTTPS_PORT);
// 發送請求
OutputStream os = s
getOutputStream();
PrintWriter pw = new PrintWriter(os);
// 設置命令
String command =
GET / HTTP/
\r\n\r\n
;
pw
print(command);
pw
flush();
// 獲得響應
InputStream is = s
getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br
readLine()) != null) {
System
out
println(line);
}
pw
close();
br
close();
s
close();
} catch (IOException e) {
System
err
println(
Error reading:
+ e);
}
}
}
在創建服務器而不是客戶機的情況下
您會從 SSLServerSocketFactory 獲得一個 ServerSocket
還請注意
J
SE
發行版中的 JSSE 庫與 JSSE
發行版中的 JSSE 庫不同
例如
ssl 軟件包現在是
ssl 軟件包
並且新增和修改了某些接口和類
在 Sun 的 J
SE
發行版中
Wrapper
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27465.html