標籤:
(1)訊息摘要:
訊息摘要(Message Digest)又稱為數字摘要(Digital Digest)。它是一個唯一對應一個訊息或文本的固定長度的值,它由一個單向Hash加密函數對訊息進行作用而產生。如果訊息在途中改變了,則接收者通過對收到訊息的新產生的摘要與原摘要比較,就可知道訊息是否被改變了。因此訊息摘要保證了訊息的完整性。 訊息摘要採用單向Hash 函數將需加密的明文"摘要"成一串128bit的密文,這一串密文亦稱為數位指紋(Finger Print),它有固定的長度,且不同的明文摘要成密文,其結果總是不同的,而同樣的明文其摘要必定一致。這樣這串摘要便可成為驗證明文是否是"真身"的"指紋"了。
這是一種與訊息認證碼結合使用以確保訊息完整性的技術。主要使用單向散列函數演算法,可用於檢驗訊息的完整性,和通過散列密碼直接以文本形式儲存等,目前廣泛使用的演算法有MD4、MD5、SHA-1,在java中進行訊息摘要很簡單:下面舉一個簡單的例子
/**
*MessageDigestTest.java
*/
import java.security.MessageDigest;
/**
*單一的訊息摘要演算法,不使用密碼.可以用來對明文訊息(如:密碼)隱藏儲存
*/
public class MessageDigestTest{
public static void main(String[] args) throws Exception{
String str="123";
byte[] plainText=str.getBytes("UTF8");
//使用getInstance("演算法")來獲得訊息摘要,這裡使用SHA-1的160位演算法
MessageDigest messageDigest=MessageDigest.getInstance("SHA-1");
System.out.println("/n"+messageDigest.getProvider().getInfo());
//開始使用演算法
messageDigest.update(plainText);
System.out.println("/nDigest:");
//輸出演算法運算結果
System.out.println(new String(messageDigest.digest(),"UTF8"));
}
}
(還可以通過訊息認證碼來進行加密實現,javax.crypto.Mac提供了一個解決方案,有興趣者可以參考相關API文檔,本文只是簡單介紹什麼是摘要演算法。)
(2)私公開金鑰和私密金鑰:
公開金鑰和私密金鑰就是俗稱的不對稱式加密方式,是從以前的對稱式加密(使用使用者名稱與密碼)方式的提高。用電子郵件的方式說明一下原理。
使用公開金鑰與私密金鑰的目的就是實現安全的電子郵件,必須實現如下目的:
1.我發送給你的內容必須加密,在郵件的傳輸過程中不能被別人看到。
2.必須保證是我發送的郵件,不是別人冒充我的。
要達到這樣的目標必鬚髮送郵件的兩人都有公開金鑰和私密金鑰。
公開金鑰,就是給大家用的,你可以通過電子郵件發布,可以通過網站讓別人下載,公開金鑰其實是用來加密/驗章用的。私密金鑰,就是自己的,必須非常小心儲存,最好加上密碼,私密金鑰是用來解密/簽章,首先就Key的所有權來說,私密金鑰只有個人擁有。公開金鑰與私密金鑰的作用是:用公開金鑰加密的內容只能用私密金鑰解密,用私密金鑰加密的內容只能用公開金鑰解密。
比如說,我要給你發送一個加密的郵件。首先,我必須擁有你的公開金鑰,你也必須擁有我的公開金鑰。
首先,我用你的公開金鑰給這個郵件加密,這樣就保證這個郵件不被別人看到,而且保證這個郵件在傳送過程中沒有被修改。你收到郵件後,用你的私密金鑰就可以解密,就能看到內容。
其次我用我的私密金鑰給這個郵件加密,發送到你手裡後,你可以用我的公開金鑰解密。因為私密金鑰只有我手裡有,這樣就保證了這個郵件是我發送的。
當A->B資料時,A會使用B的公開金鑰加密,這樣才能確保只有B能解開,否則普羅福士都能解開加密的訊息,就是去了資料的保密性。驗證方面則是使用簽驗章的機制,A傳資料給大家時,會以自己的私密金鑰做簽章,如此所有收到訊息的人都可以用A的公開金鑰進行驗章,便可確認訊息是由A發出來的了。
I.私匙加密解密執行個體:
/**
*PrivateTest.java
*/
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
/**
*私鈅加密,保證訊息機密性
*/
public class PrivateTest{
public static void main(String[] args) throws Exception{
String str="123";
byte[] plainText=str.getBytes("UTF8");
//通過KeyGenerator形成一個key
System.out.println("/nStart generate AES key");
KeyGenerator keyGen=KeyGenerator.getInstance("AES");
keyGen.init(128);
Key key=keyGen.generateKey();
System.out.println("Finish generating DES key");
//獲得一個私鈅加密類Cipher,ECB是加密方式,PKCS5Padding是填充方法
Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");
System.out.println("/n"+cipher.getProvider().getInfo());
//使用私鈅加密
System.out.println("/nStart encryption:");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));
//使用私鈅解密
System.out.println("/nStart decryption:");
cipher.init(Cipher.DECRYPT_MODE,key);
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}
II.公匙加密,私匙解密執行個體:
/**
*PublicTest.java
*/
import java.security.Key;
import javax.crypto.Cipher;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
/**
*一個簡單的公鈅加密例子,Cipher類使用KeyPairGenerator產生的公鈅和私鈅
*/
public class PublicTest{
public static void main(String[] args) throws Exception{
String str="123";
byte[] plainText=str.getBytes("UTF8");
//構成一個RSA密鑰
System.out.println("/nStart generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//獲得一個RSA的Cipher類,使用公鈅加密
Cipher cipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
System.out.println("/n"+cipher.getProvider().getInfo());
System.out.println("/nStart encryption");
cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());
byte[] cipherText=cipher.doFinal(plainText);
System.out.println("Finish encryption:");
System.out.println(new String(cipherText,"UTF8"));
//使用私鈅解密
System.out.println("/nStart decryption");
cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());
byte[] newPlainText=cipher.doFinal(cipherText);
System.out.println("Finish decryption:");
System.out.println(new String(newPlainText,"UTF8"));
}
}
(3)數位簽章:
I.電子商務中資料轉送的幾個安全性需求
1. 資料的保密性:用於防止非法使用者進入系統及合法使用者對系統資源的非法使用;通過對一些敏感的資料檔案進行加密來保護系統之間的資料交換,防止除接收方之外的第三方截獲資料及即使擷取檔案也無法得到其內容。如在電子交易中,避免遭到駭客的襲擊使信用卡資訊丟失的問題。
2. 資料的完整性:防止非法使用者對進行交換的資料進行無意或惡意的修改、插入,防止交換的資料丟失等。
3. 資料的不可否認性:對資料和資訊的來源進行驗證,以確保資料由合法的使用者發出;防止資料發送方在發出資料後又加以否認;同時防止接收方在收到資料後又否認曾收到過此資料及篡改資料。
上述需求對應於防火牆、加密、數位簽章、身份認證等技術,但其關鍵在於數位簽章技術。
II. 數位簽章的含義
數位簽章是通過一個單向函數對要傳送的報文進行處理得到的用以認證報文來源並核實報文是否發生變化的一個字母數字串。
III.數位簽章的實現方法
實現數位簽章有很多方法,目前數位簽章採用較多的是公開金鑰加密技術,如基於RSA Date Security 公司的PKCS( Public Key Cryptography Standards )、Digital Signature Algorithm、x.509、PGP(Pretty Good Privacy). 1994年美國標準與技術協會公布了數位簽章標準 (DSS)(DSS)而使公開金鑰加密技術廣泛應用。&127;公開金鑰加密系統採用的是非對稱式加密演算法。
IIII.執行個體
**
*DigitalSignatureTest.java
*/
import java.security.Signature;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.SignatureException;
/**
*數位簽章,使用RSA私密金鑰對對訊息摘要簽名,然後使用公鈅驗證 測試
*/
public class DigitalSignatureTest{
public static void main(String[] args) throws Exception{
String str="123";
byte[] plainText=str.getBytes("UTF8");
//形成RSA公開金鑰對
System.out.println("/nStart generating RSA key");
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key=keyGen.generateKeyPair();
System.out.println("Finish generating RSA key");
//使用私鈅簽名
Signature sig=Signature.getInstance("SHA1WithRSA");
sig.initSign(key.getPrivate());
sig.update(plainText);
byte[] signature=sig.sign();
System.out.println(sig.getProvider().getInfo());
System.out.println("/nSignature:");
System.out.println(new String(signature,"UTF8"));
//使用公鈅驗證
System.out.println("/nStart signature verification");
sig.initVerify(key.getPublic());
sig.update(plainText);
try{
if(sig.verify(signature)){
System.out.println("Signature verified");
}else System.out.println("Signature failed");
}catch(SignatureException e){
System.out.println("Signature failed");
}
}
}
(4)數位憑證
I.概念:是數字形式的標識,與護照或駕駛員執照十分相似。數位憑證是數字憑據,它提供有關實體標識的資訊以及其他支援資訊。數位憑證是由成為憑證授權單位(CA)的權威機構頒發的。由於數位憑證有認證權威機構頒發,因此由該權威機構擔保認證資訊的有效性。此外,數位憑證只在特定的時間段內有效。
數位憑證包含認證中所標識的實體的公開金鑰(就是說你的認證裡有你的公開金鑰),由於認證將公開金鑰與特定的個人匹配,並且該認證的真實性由頒發機構保證(就是說可以讓大家相信你的認證是真的),因此,數位憑證為如何找到使用者的公開金鑰並知道它是否有效這一問題提供瞭解決方案。
II.數位憑證的原理
數位憑證採用公開金鑰體制,即利用一對互相匹配的密鑰進行加密、解密。每個使用者自己設定一把特定的僅為本人所知的私人密鑰(私密金鑰),用它進行解密和簽名;同時設定一把公用密鑰(公開金鑰)並由本人公開,為一組使用者所共用,用於加密和驗證簽名。當發送一份保密檔案時,發送方使用接收方的公開金鑰對資料加密,而接收方則使用自己的私密金鑰解密,這樣資訊就可以安全無誤地到達目的地了。通過數位手段保證加密過程是一個無法復原過程,即只有用私人密鑰才能解密.在公開密鑰密碼體制中,常用的一種是RSA體制。
使用者也可以採用自己的私密金鑰對資訊加以處理,由於密鑰僅為本人所有,這樣就產生了別人無法產生的檔案,也就形成了數位簽章。採用數位簽章,能夠確認以下兩點:
(1)保證資訊是由簽名者自己簽名發送的,簽名者不能否認或難以否認;
(2)保證資訊自簽發後到收到為止未曾作過任何修改,簽發的檔案是真實檔案。
III.java執行個體操作:
密鑰庫:java平台為你提供了密鑰庫,用作密鑰和認證的資產庫。從物理上講,密鑰庫是預設名稱為 .keystore 的檔案(有一個選項使它成為加密檔案)。密鑰和認證可以擁有名稱(稱為別名),每個別名都由唯一的密碼保護。密鑰庫本身也受密碼保護;您可以選擇讓每個別名密碼與主要金鑰庫密碼匹配。
使用工具keytool,進行自我認證:
1、建立密鑰庫keytool -genkey -v -alias YourKeyName -keyalg RSA 預設在自己的home目錄下(windows系統是c:/documents and settings/<你的使用者名稱> 目錄下的.keystore檔案),建立我們用 RSA 演算法產生別名為 feiUserKey 的自簽名的認證,如果使用了-keystore mm 就在目前的目錄下建立一個密鑰庫mm檔案來儲存密鑰和認證。
2、查看認證:keytool -list 列舉了密鑰庫的所有的認證
也可以在dos下輸入keytool -help查看協助。
(5)JAR的簽名
前面我們已將講了怎樣建立自己的認證了,現在可以開始瞭解怎樣對JAR檔案簽名,JAR檔案在Java中相當於 ZIP 檔案,允許將多個 Java 類檔案打包到一個具有 .jar 副檔名的檔案中,然後可以對這個jar檔案進行數位簽章,以證實其來源和真實性。該 JAR 檔案的接收方可以根據發送方的簽名決定是否信任該代碼,並可以確信該內容在接收之前沒有被篡改過。同時在部署中,可以通過在策略檔案中放置存取控制語句根據簽名者的身份分配對機器資源的訪問權。這樣,有些Applet的安全檢驗訪問就得以進行。
使用jarsigner工具可以對jar檔案進行簽名:
現在假設我們有個Test.jar檔案(可以使用jar命令列工具產生):
jarsigner Test.jar YourKeyName (這裡我們上面建立了該別名的認證) ,詳細資料可以輸入jarsigner查看協助
驗證其真實性:jarsigner -verify Test.jar(注意,驗證的是jar是否被修改了,但不檢驗減少的,如果增加了新的內容,也提示,但減少的不會提示。)
使用Applet中::<applet code="Test.class" archive="Test.jar" width="150" height="100"></applet>然後瀏覽器就會提示你:准許這個會話-拒絕-始終准許-查看認證等。
(6)安全通訊端層(SSL Secure Sockets Layer)和傳輸層安全性(TLS Transport Layer Security)
I.簡介:
安全通訊端層 (SSL):一種由 Netscape Communications 開發的提議開放式標準,用以建立安全通訊通道,以防止如信用卡號等這樣的重要訊息被截獲。
安全通訊端層是用於伺服器之上的一個加密系統,它可以確保在客戶機與伺服器之間傳輸的資料仍然是安全與隱密的。要使伺服器和客戶機使用 SSL 進行安全的通訊,伺服器必須有兩樣東西:
金鑰組(Key pair) —— 一個金鑰組包括一個公開金鑰和一個私密金鑰。這兩個密鑰用來對訊息進行加密和解密,以確保在網際網路上傳輸時的隱密性和機密性。
認證(Certificate) —— 認證用來進行身分識別驗證或者身份確認。認證可以是自簽(self-signed)認證,也可以是頒發(issued)認證。自簽認證是為自己私人的 Web 網路建立的認證。頒發認證是認證中心(certificate authority,CA)或者認證簽署者提供(頒發)給您的認證。
SSL 使用安全握手來初始化客戶機與伺服器之間的安全連線。在握手期間,客戶機和伺服器對它們將要為此會話使用的密鑰及加密方法達成一致。客戶機使用伺服器憑證驗證伺服器。握手之後,SSL 被用來加密和解密 HTTPS(組合 SSL 和 HTTP 的一個獨特協議)請求和伺服器響應中的所有資訊,包括:
客戶機正在請求的 URL。
提交的表單的內容。
訪問授權資訊(比如使用者名稱和密碼)。
所有在客戶機與伺服器之間發送的資料。
II.總結:
安全通訊端層和傳輸層安全性是用於在客戶機和伺服器之間構建安全的通訊通道的協議。它也用來為客戶機證明伺服器,以及(不太常用的)為伺服器認證客戶機。該協議在瀏覽器應用程式中比較常見,瀏覽器視窗底部的鎖表明 SSL/TLS 有效:
1)當使用 SSL/TLS(通常使用 https:// URL)向網站進行請求時,從伺服器向客戶機發送一個認證。客戶機使用已安裝的公用 CA 憑證通過這個認證驗證伺服器的身份,然後檢查 IP 名稱(機器名)與客戶機串連的機器是否匹配。
2)客戶機產生一些可以用來產生對話的私密金鑰(稱為工作階段金鑰)的隨機資訊,然後用伺服器的公開金鑰對它加密並將它發送到伺服器。伺服器用自己的私密金鑰解密訊息,然後用該隨機資訊派生出和客戶機一樣的私人工作階段金鑰。通常在這個階段使用 RSA 公開金鑰演算法。
3)客戶機和伺服器使用私人工作階段金鑰和私密金鑰演算法(通常是 RC4)進行通訊。使用另一個密鑰的訊息認證碼來確保訊息的完整性。
java中javax.net.ssl.SSLServerSocketFactory類提供了一個很好的SSLServerSocker的工廠類,熟悉Socket編程的讀者可以去練習。當編寫完伺服器端之後,在瀏覽器上輸入https://主機名稱:連接埠 就會通過SSL/TLS進行通話了。注意:運行服務端的時候要帶系統內容變數運行:javax.net.ssl.keyStore=密鑰庫(建立認證時,名字應該為主機名稱,比如localhost)和javax.net.ssl.keyStorePassword=你的密碼
Java的安全學習(包括加密,數位簽章,認證和認證)