⑴ 摘要認證是什麼
對於普通的非敏感數據,我們更多關注其真實性和准確性,因此,如何在通信過程中保障數據不被篡改,首當其沖成為需要考慮的問題。鑒於使用HTTPS2性能上的成本以及需要額外申請CA證書,在這種情況下,一般採用對參數和響應進行摘要的方法,即能夠滿足需求。
針對每次請求和響應,按照一定的規則生成數字摘要,數字摘要需要涵蓋客戶端與服務端通信的內容,以及雙方約定好的「鹽」,以此來保障請求與響應不被第三方篡改。常見的摘要演算法包括MD5、SHA等,關於摘要演算法的介紹,前面章節已有詳細介紹,此處便不再贅述。由於傳遞端和接收端都認為HTTP協議的請求參數是無序的,因此客戶端與服務端雙方需要約定好參數的排序方式。請求的參數經過排序後,再將參數名稱和值經過一定的策略組織起來,加上一個密鑰secret,也就是所謂的「鹽」,然後通過約定的摘要演算法生成數字摘要,傳遞給服務端。
在服務端接收到客戶端傳遞的參數後,服務端會採用與客戶端相同的策略對參數進行排序,並且加上相同的secret,採用相同的摘要方式生成摘要串。由於相同內容經過相同的摘要演算法,生成的摘要內容必定是相同的。將服務端生成的摘要串與客戶端生成摘要串進行比較,這樣可以得知參數內容是否被篡改。同樣的,服務端返回的響應也需要加上 secret,採用約定好的摘要演算法生成相應的摘要,並將生成的摘要作為響應的一部分,返回給客戶端,以便驗證服務端返回數據的合法性。
當客戶端接收到服務端的響應後,加上相同的secret進行拼接,並採用與服務端相同的摘要演算法進行摘要,生成的摘要串與服務端傳遞過來的摘要串進行比較,這樣便可得知服務端的響應是否被篡改。
由於摘要演算法的不可逆性,並且大部分情況下不同的請求參數會有不同的服務端響應,鑒於參數和響應的多變性,摘要認證這種方式能夠在一定程度上防止信息被篡改,保障通信的安全。但是,摘要認證的安全性取決於secret的安全性,由於服務端與客戶端採用的是相同的secret,一旦secret泄露,通信的安全則無法保障。
簡單的Java加密演算法有:
第一種. BASE
Base是網路上最常見的用於傳輸Bit位元組代碼的編碼方式之一,大家可以查看RFC~RFC,上面有MIME的詳細規范。Base編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base來將一個較長的唯一標識符(一般為-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
第二種. MD
MD即Message-Digest Algorithm (信息-摘要演算法),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD的前身有MD、MD和MD。
MD演算法具有以下特點:
壓縮性:任意長度的數據,算出的MD值長度都是固定的。
容易計算:從原數據計算出MD值很容易。
抗修改性:對原數據進行任何改動,哪怕只修改個位元組,所得到的MD值都有很大區別。
弱抗碰撞:已知原數據和其MD值,想找到一個具有相同MD值的數據(即偽造數據)是非常困難的。
強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD值,是非常困難的。
MD的作用是讓大容量信息在用數字簽名軟體簽署私人密鑰前被」壓縮」成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進制數字串)。除了MD以外,其中比較有名的還有sha-、RIPEMD以及Haval等。
第三種.SHA
安全哈希演算法(Secure Hash Algorithm)主要適用於數字簽名標准(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度小於^位的消息,SHA會產生一個位的消息摘要。該演算法經過加密專家多年來的發展和改進已日益完善,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或信息),並把它們轉化為長度較短、位數固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程。散列函數值可以說是對明文的一種「指紋」或是「摘要」所以對散列值的數字簽名就可以視為對此明文的數字簽名。
SHA-與MD的比較
因為二者均由MD導出,SHA-和MD彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同:
對強行攻擊的安全性:最顯著和最重要的區別是SHA-摘要比MD摘要長 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對MD是^數量級的操作,而對SHA-則是^數量級的操作。這樣,SHA-對強行攻擊有更大的強度。
對密碼分析的安全性:由於MD的設計,易受密碼分析的攻擊,SHA-顯得不易受這樣的攻擊。
速度:在相同的硬體上,SHA-的運行速度比MD慢。
第四種.HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。
⑶ 分享Java常用幾種加密演算法
簡單的Java加密演算法有:
第一種. BASE
Base是網路上最常見的用於傳輸Bit位元組代碼的編碼方式之一,大家可以查看RFC~RFC,上面有MIME的詳細規范。Base編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base來將一個較長的唯一標識符(一般為-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
第二種. MD
MD即Message-Digest Algorithm (信息-摘要演算法),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD的前身有MD、MD和MD。廣泛用於加密和解密技術,常用於文件校驗。校驗?不管文件多大,經過MD後都能生成唯一的MD值。好比現在的ISO校驗,都是MD校驗。怎麼用?當然是把ISO經過MD後產生MD的值。一般下載linux-ISO的朋友都見過下載鏈接旁邊放著MD的串。就是用來驗證文件是否一致的。
MD演算法具有以下特點:
壓縮性:任意長度的數據,算出的MD值長度都是固定的。
容易計算:從原數據計算出MD值很容易。
抗修改性:對原數據進行任何改動,哪怕只修改個位元組,所得到的MD值都有很大區別。
弱抗碰撞:已知原數據和其MD值,想找到一個具有相同MD值的數據(即偽造數據)是非常困難的。
強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD值,是非常困難的。
MD的作用是讓大容量信息在用數字簽名軟體簽署私人密鑰前被」壓縮」成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進制數字串)。除了MD以外,其中比較有名的還有sha-、RIPEMD以及Haval等。
第三種.SHA
安全哈希演算法(Secure Hash Algorithm)主要適用於數字簽名標准(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度小於^位的消息,SHA會產生一個位的消息摘要。該演算法經過加密專家多年來的發展和改進已日益完善,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或信息),並把它們轉化為長度較短、位數固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程。散列函數值可以說是對明文的一種「指紋」或是「摘要」所以對散列值的數字簽名就可以視為對此明文的數字簽名。
SHA-與MD的比較
因為二者均由MD導出,SHA-和MD彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同:
對強行攻擊的安全性:最顯著和最重要的區別是SHA-摘要比MD摘要長 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對MD是^數量級的操作,而對SHA-則是^數量級的操作。這樣,SHA-對強行攻擊有更大的強度。
對密碼分析的安全性:由於MD的設計,易受密碼分析的攻擊,SHA-顯得不易受這樣的攻擊。
速度:在相同的硬體上,SHA-的運行速度比MD慢。
第四種.HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。
⑷ 摘要演算法的特點是什麼
「消息摘要」(Message Digest)是一種能產生特殊輸出格式的演算法,這種加密演算法的特點是無論用戶輸入什麼長度的原始數據,經過計算後輸出的密文都是固定長度的,這種演算法的原理是根據一定的運算規則對原數據進行某種形式的提取,這種提取就是「摘要」,被「摘要」的數據內容與原數據有密切聯系,只要原數據稍有改變,輸出的「摘要」便完全不同,因此基於這種原理的演算法便能對數據完整性提供較為健全的保障。但是,由於輸出的密文是提取原數據經過處理的定長值,所以它已經不能還原為原數據,即消息摘要演算法是「不可逆」的,理論上無法通過反向運算取得原數據內容,因此它通常只能被用來做數據完整性驗證,而不能作為原數據內容的加密方案使用,否則誰也無法還原。
⑸ 摘要演算法的分類
1、CRC8、CRC16、CRC32
CRC(Cyclic Rendancy Check,循環冗餘校驗)演算法出現時間較長,應用也十分廣泛,尤其是通訊領域,現在應用最多的就是 CRC32 演算法,它產生一個4位元組(32位)的校驗值,一般是以8位十六進制數,如FA 12 CD 45等。CRC演算法的優點在於簡便、速度快,嚴格的來說,CRC更應該被稱為數據校驗演算法,但其功能與數據摘要演算法類似,因此也作為測試的可選演算法。
在 WinRAR、WinZIP 等軟體中,也是以 CRC32 作為文件校驗演算法的。一般常見的簡單文件校驗(Simple File Verify – SFV)也是以 CRC32演算法為基礎,它通過生成一個後綴名為 .SFV 的文本文件,這樣可以任何時候可以將文件內容 CRC32運算的結果與 .SFV 文件中的值對比來確定此文件的完整性。
與 SFV 相關工具軟體有很多,如MagicSFV、MooSFV等。
2、MD2 、MD4、MD5
這是應用非常廣泛的一個演算法家族,尤其是 MD5(Message-Digest Algorithm 5,消息摘要演算法版本5),它由MD2、MD3、MD4發展而來,由Ron Rivest(RSA公司)在1992年提出,被廣泛應用於數據完整性校驗、數據(消息)摘要、數據加密等。MD2、MD4、MD5 都產生16位元組(128位)的校驗值,一般用32位十六進制數表示。MD2的演算法較慢但相對安全,MD4速度很快,但安全性下降,MD5比MD4更安全、速度更快。
在互聯網上進行大文件傳輸時,都要得用MD5演算法產生一個與文件匹配的、存儲MD5值的文本文件(後綴名為 .md5或.md5sum),這樣接收者在接收到文件後,就可以利用與 SFV 類似的方法來檢查文件完整性,絕大多數大型軟體公司或開源組織都是以這種方式來校驗數據完整性,而且部分操作系統也使用此演算法來對用戶密碼進行加密,另外,它也是目前計算機犯罪中數據取證的最常用演算法。
與MD5 相關的工具有很多,如 WinMD5等。
3、SHA1、SHA256、SHA384、SHA512
SHA(Secure Hash Algorithm)是由美國專門制定密碼演算法的標准機構—— 美國國家標准技術研究院(NIST)制定的,SHA系列演算法的摘要長度分別為:SHA為20位元組(160位)、SHA256為32位元組(256位)、 SHA384為48位元組(384位)、SHA512為64位元組(512位),由於它產生的數據摘要的長度更長,因此更難以發生碰撞,因此也更為安全,它是未來數據摘要演算法的發展方向。由於SHA系列演算法的數據摘要長度較長,因此其運算速度與MD5相比,也相對較慢。
SHA1的應用較為廣泛,主要應用於CA和數字證書中,另外在互聯網中流行的BT軟體中,也是使用SHA1來進行文件校驗的。
4、RIPEMD、PANAMA、TIGER、ADLER32 等
RIPEMD是Hans Dobbertin等3人在對MD4,MD5缺陷分析基礎上,於1996年提出來的,有4個標准128、160、256和320,其對應輸出長度分別為16位元組、20位元組、32位元組和40位元組。
TIGER由Ross在1995年提出。Tiger號稱是最快的Hash演算法,專門為64位機器做了優化。
⑹ 數字摘要是由什麼演算法得來的
你想用什麼演算法都行,比如MD5,SHA1等,舉個例子:
byte[] digest = MessageDigest.getInstance("MD5").digest("這是很長很長的一大段文字。。。".getBytes("UTF-8"));
這是很長很長的一大段文字,變成了32位元組,就算實現了摘要
⑺ 演算法的三種基本結構是
演算法有順序結構、條件分支結構、循環結構三種基本邏輯結構。
1、順序結構:順序結構是最簡單的演算法結構,語句與語句之間,框與框之間是按從上到下的順序進行的,它是由若干個依次執行的處理步驟組成的。
它是任何一個演算法都離不開的一種基本演算法結構。順序結構在程序框圖中的體現就是用流程線將程序框自上而下地連接起來,按順序執行演算法步驟。
2、條件結構:
條件結構是指在演算法中通過對條件的判斷,根據條件是否成立而選擇不同流向的演算法結構。
條件P是否成立而選擇執行A框或B框。無論P條件是否成立,只能執行A框或B框之一,不可能同時執行A框和B框,也不可能A框、B框都不執行。一個判斷結構可以有多個判斷框。
3、循環結構
在一些演算法中,經常會出現從某處開始,按照一定條件,反復執行某一處理步驟的情況,這就是循環結構,反復執行的處理步驟為循環體,顯然,循環結構中一定包含條件結構。循環結構又稱重復結構,循環結構可細分為兩類:
一類是當型循環結構,如下左圖所示,它的功能是當給定的條件P成立時,執行A框,A框執行完畢後,再判斷條件P是否成立,如果仍然成立,再執行A框,如此反復執行A框,直到某一次條件P不成立為止,此時不再執行A框,離開循環結構。
另一類是直到型循環結構,如下右圖所示,它的功能是先執行,然後判斷給定的條件P是否成立,如果P仍然不成立,則繼續執行A框,直到某一次給定的條件P成立為止,此時不再執行A框,離開循環結構。
(7)三種摘要演算法擴展閱讀
共同特點
(1)只有一個入口和出口
(2)結構內的每一部分都有機會被執行到,也就是說對每一個框來說都應當有一條從入口到出口的路徑通過它,如圖中的A,沒有一條從入口到出口的路徑通過它,就是不符合要求的演算法結構。
(3)結構內不存在死循環,即無終止的循環。
⑻ 摘要演算法的介紹
數據摘要演算法是密碼學演算法中非常重要的一個分支,它通過對所有數據提取指紋信息以實現數據簽名、數據完整性校驗等功能,由於其不可逆性,有時候會被用做敏感信息的加密。數據摘要演算法也被稱為哈希(Hash)演算法、散列演算法。
⑼ 什麼是報文摘要演算法
本文描述了MD5報文摘要演算法,此演算法將對輸入的任意長度的信息進行計算,產生一個128位
長度的「指紋」或「報文摘要」,假定兩個不同的文件產生相同的報文摘要或由給定的報文摘要產生
原始信息在計算上是行不通的。MD5演算法適合用在數據簽名應用中,在此應用中,一個大的文件必
須在類似RSA演算法的公用密鑰系統中用私人密鑰加密前被「壓縮」在一種安全模式下。
MD5演算法能在32位機器上能以很快的速度運行。另外,MD5演算法不需要任何大型的置換列表。
此演算法編碼很簡潔。MD5演算法是MD4報文摘要演算法的擴展。MD5演算法稍慢於MD4演算法,但是在設
計上比MD4演算法更加「保守」。設計MD5是因為MD4演算法被採用的速度太快,以至於還無法證明
它的正確性,因為MD4演算法速度非常快,它處在遭受成功秘密攻擊的「邊緣」。MD5後退了一步,
它舍棄了一些速度以求更好的安全性。它集中了不同的評論家提出的建議,並採取了一些附加的優化
措施。它被放在公共的地方以求公眾的評論意見,它可能當作一個標准被採納。
作為基於OSI的應用,MD5的對象標識符是:
md5OBJECTIDENTIFIER::=
iso(1)member-body(2)US(840)rsadsi(113549)digestAlgorithm(2)5}
在X.509類型AlgorithmIdentifier[3]中,MD5演算法參數應該包括NULL類型。
2 術語和符號
本文中一個「字」是32位,一個「位元組」是8位。一系列位串可看成是一系列位元組的普通形式,
其中的連續的8位看成一個位元組,高位在前,同理一系列位元組串可看成是一系列32位的字,其中每
個連續的4個位元組當作一個字,地位在前。
我們定義x_i代表「x減去I".如果下劃線左邊的是一個表達式,則用括弧括住,如:
x_{i+1}。同樣我們用^代表求冪,這樣x^i則代表x的i次冪。
符號「+」代表字的加,X<<<s代表32位的值X循環左移s位,not(X)代表X的按位
補運算,XvY表示X和Y的按位或運算,XxorY代表X和Y的按位異或運算,XY代表
X和Y的按位與運算。
3 MD5演算法描述
我們假設有一個b位長度的輸入信號,希望產生它的報文摘要,此處b是一個非負整數,b也可
能是0,不一定必須是8的整數倍,它可能是任意大的長度。我們設想信號的比特流如下所示:
m_0m_1...m_{b-1}
下面的5步計算信息的報文摘要。
(1)補位
MD5演算法是對輸入的數據進行補位,使得如果數據位長度LEN對512求余的結果是448。即數
據擴展至K*512+448位。即K*64+56個位元組,K為整數。補位操作始終要執行,即使數據長度LEN
對512求余的結果已是448。
具體補位操作:補一個1,然後補0至滿足上述要求。總共最少要補一位,最多補512位。
(2)補數據長度
用一個64位的數字表示數據的原始長度b,把b用兩個32位數表示。那麼只取B的低64位。
當遇到b大於2^64這種極少遇到的情況時,這時,數據就被填補成長度為512位的倍數。也就是說,
此時的數據長度是16個字(32位)的整數倍數。用M[0...N-1]表示此時的數據,其中的N是16
的倍數。
(3)初始化MD緩沖器
用一個四個字的緩沖器(A,B,C,D)來計算報文摘要,A,B,C,D分別是32位的寄存器,初
始化使用的是十六進製表示的數字
A=0X01234567
B=0X89abcdef
C=0Xfedcba98
D=0X76543210
(4)處理位操作函數
首先定義4個輔助函數,每個函數的輸入是三個32位的字,輸出是一個32位的字。
X,Y,Z為32位整數。
F(X,Y,Z)=XYvnot(X)Z
G(X,Y,Z)=XZvYnot(Z)
H(X,Y,Z)=XxorYxorZ
I(X,Y,Z)=Yxor(Xvnot(Z))
這一步中使用一個64元素的常數組T[1...64],它由sine函數構成,T[i]表示數組中的第i個元
素,它的值等於經過4294967296次abs(sin(i))後的值的整數部分(其中i是弧度)。T[i]為32位
整數用16進製表示
⑽ 基於java語言的數字簽名
Java加密和數字簽名編程快速入門
本文主要談一下密碼學中的加密和數字簽名,以及其在java中如何進行使用。對密碼學有興趣的夥伴,推薦看Bruce Schneier的著作:Applied Crypotography。在jdk1.5的發行版本中安全性方面有了很大的改進,也提供了對RSA演算法的直接支持,現在我們從實例入手解決問題(本文僅是作為簡單介紹):
一、密碼學上常用的概念
1)消息摘要:
這是一種與消息認證碼結合使用以確保消息完整性的技術。主要使用單向散列函數演算法,可用於檢驗消息的完整性,和通過散列密碼直接以文本形式保存等,目前廣泛使用的演算法有MD4、MD5、SHA-1,jdk1.5對上面都提供了支持,在java中進行消息摘要很簡單, java.security.MessageDigest提供了一個簡易的操作方法:
/**
*MessageDigestExample.java
*Copyright 2005-2-16
*/
import java.security.MessageDigest;
/**
*單一的消息摘要演算法,不使用密碼.可以用來對明文消息(如:密碼)隱藏保存
*/
public class MessageDigestExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java MessageDigestExample text");
System.exit(1);
}
byte[] plainText=args[0].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)私鑰加密:
消息摘要只能檢查消息的完整性,但是單向的,對明文消息並不能加密,要加密明文的消息的話,就要使用其他的演算法,要確保機密性,我們需要使用私鑰密碼術來交換私有消息。
這種最好理解,使用對稱演算法。比如:A用一個密鑰對一個文件加密,而B讀取這個文件的話,則需要和A一樣的密鑰,雙方共享一個私鑰(而在web環境下,私鑰在傳遞時容易被偵聽):
使用私鑰加密的話,首先需要一個密鑰,可用javax.crypto.KeyGenerator產生一個密鑰(java.security.Key),然後傳遞給一個加密工具(javax.crypto.Cipher),該工具再使用相應的演算法來進行加密,主要對稱演算法有:DES(實際密鑰只用到56位),AES(支持三種密鑰長度:128、192、256位),通常首先128位,其他的還有DESede等,jdk1.5種也提供了對對稱演算法的支持,以下例子使用AES演算法來加密:
/**
*PrivateExmaple.java
*Copyright 2005-2-16
*/
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.Key;
/**
*私鈅加密,保證消息機密性
*/
public class PrivateExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PrivateExample <text>");
System.exit(1);
}
byte[] plainText=args[0].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"));
}
}
3)公鑰加密:
上面提到,私鑰加密需要一個共享的密鑰,那麼如何傳遞密鑰呢?web環境下,直接傳遞的話很容易被偵聽到,幸好有了公鑰加密的出現。公鑰加密也叫不對稱加密,不對稱演算法使用一對密鑰對,一個公鑰,一個私鑰,使用公鑰加密的數據,只有私鑰能解開(可用於加密);同時,使用私鑰加密的數據,只有公鑰能解開(簽名)。但是速度很慢(比私鑰加密慢100到1000倍),公鑰的主要演算法有RSA,還包括Blowfish,Diffie-Helman等,jdk1.5種提供了對RSA的支持,是一個改進的地方:
/**
*PublicExample.java
*Copyright 2005-2-16
*/
import java.security.Key;
import javax.crypto.Cipher;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
/**
*一個簡單的公鈅加密例子,Cipher類使用KeyPairGenerator生成的公鈅和私鈅
*/
public class PublicExample{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java PublicExample <text>");
System.exit(1);
}
byte[] plainText=args[0].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"));
}
}
4)數字簽名:
數字簽名,它是確定交換消息的通信方身份的第一個級別。上面A通過使用公鑰加密數據後發給B,B利用私鑰解密就得到了需要的數據,問題來了,由於都是使用公鑰加密,那麼如何檢驗是A發過來的消息呢?上面也提到了一點,私鑰是唯一的,那麼A就可以利用A自己的私鑰進行加密,然後B再利用A的公鑰來解密,就可以了;數字簽名的原理就基於此,而通常為了證明發送數據的真實性,通過利用消息摘要獲得簡短的消息內容,然後再利用私鑰進行加密散列數據和消息一起發送。java中為數字簽名提供了良好的支持,java.security.Signature類提供了消息簽名:
/**
*DigitalSignature2Example.java
*Copyright 2005-2-16
*/
import java.security.Signature;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.SignatureException;
/**
*數字簽名,使用RSA私鑰對對消息摘要簽名,然後使用公鈅驗證 測試
*/
public class DigitalSignature2Example{
public static void main(String[] args) throws Exception{
if(args.length!=1){
System.err.println("Usage:java DigitalSignature2Example <text>");
System.exit(1);
}
byte[] plainText=args[0].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");
}
}
}
5)數字證書。
還有個問題,就是公鑰問題,A用私鑰加密了,那麼B接受到消息後,用A提供的公鑰解密;那麼現在有個討厭的C,他把消息攔截了,然後用自己的私鑰加密,同時把自己的公鑰發給B,並告訴B,那是A的公鑰,結果....,這時候就需要一個中間機構出來說話了(相信權威,我是正確的),就出現了Certificate Authority(也即CA),有名的CA機構有Verisign等,目前數字認證的工業標準是:CCITT的X.509:
數字證書:它將一個身份標識連同公鑰一起進行封裝,並由稱為認證中心或 CA 的第三方進行數字簽名。
密鑰庫:java平台為你提供了密鑰庫,用作密鑰和證書的資源庫。從物理上講,密鑰庫是預設名稱為 .keystore 的文件(有一個選項使它成為加密文件)。密鑰和證書可以擁有名稱(稱為別名),每個別名都由唯一的密碼保護。密鑰庫本身也受密碼保護;您可以選擇讓每個別名密碼與主密鑰庫密碼匹配。
使用工具keytool,我們來做一件自我認證的事情吧(相信我的認證):
1、創建密鑰庫keytool -genkey -v -alias feiUserKey -keyalg RSA 默認在自己的home目錄下(windows系統是c:\documents and settings\<你的用戶名> 目錄下的.keystore文件),創建我們用 RSA 演算法生成別名為 feiUserKey 的自簽名的證書,如果使用了-keystore mm 就在當前目錄下創建一個密鑰庫mm文件來保存密鑰和證書。
2、查看證書:keytool -list 列舉了密鑰庫的所有的證書
也可以在dos下輸入keytool -help查看幫助。