該文中的內(nèi)容來源于 Oracle 的官方文檔 Java SE Tools Reference 。Oracle 在 Java 方面的文檔是非常完善的。對 Java 8 感興趣的朋友,可以直接找到這個總?cè)肟?Java SE 8 Documentation ,想閱讀什么就點什么。本博客不定期從 Oracle 官網(wǎng)搬磚。這里介紹的工具是 keytool 。
在 Web 世界里,安全是一個重之又重的課題,甚至是美國政府都禁止某些加密解密算法的出口。 Java 和 Linux 都是 Web 領(lǐng)域的領(lǐng)頭羊,各種加解密的算法和管理工具一應(yīng)俱全,例如 GnuPG 就是一個不錯的安全套件。但是在這里,只展示一下 JDK 中的 keytool 工具的使用方法。
先來說一下加解密算法的分類?;旧峡梢苑譃槿悾鼈兎謩e是對稱性解密算法、非對稱性加密算法和消息摘要算法。每一類算法中又有多個不同的具體算法。對于這些算法,我們不要求完全掌握,但是對于各類算法的特點和用途是一定要了解的,對于一些常見的名字,如 DES、AES、RSA、DSA、MD5、SHA1 等,一定要熟悉,至少要知道它們分別屬于哪類算法。
對稱性加密算法使用同一個密鑰對信息進(jìn)行加密和解密,其信息的安全性一部分取決于加密算法和密鑰的長度,另一部分取決于密鑰在傳遞過程中是否會被截獲或盜取。非對稱性加密算法使用兩個密鑰分別對信息進(jìn)行加密和解密,這兩個密鑰稱為私鑰/公鑰對。使用私鑰加密的信息必須使用公鑰解密,反之亦然。公鑰可以公開發(fā)布,私鑰由加密方保存,絕對不公開,將私鑰被截獲或竊取的可能性降到最低,因此非對稱性加密算法的安全性比對稱性加密算法的安全性更高。既然非對稱性加密算法比對稱性加密算法安全性更高,那對稱性加密算法有什么存在的必要呢?這是因為對稱性加密算法的運算速度更快?,F(xiàn)實中,往往將對稱性加密算法和非對稱性加密算法結(jié)合使用,對于要傳輸?shù)拇髩K數(shù)據(jù)使用對稱性加密算法加密,然后對加密使用的密鑰使用非對稱性加密算法進(jìn)行加密,這樣既可以獲得更高的安全性,又可以獲得更高的加解密運算速度。常用的對稱性加密算法有DES算法、AES算法、3DES算法、TDEA算法、Blowfish算法、RC5算法、IDEA算法。常用的非對稱性加密算法有DSA算法、RSA算法、Elgamal算法、背包算法、Rabin算法、D-H算法、ECC算法(橢圓曲線加密算法)。
消息摘要算法的主要目的是對數(shù)據(jù)生成摘要。消息摘要算法不需要密鑰,只有輸入相同的數(shù)據(jù)才能得到相同的摘要,而且不可能從摘要反過來推算出數(shù)據(jù)。常用的消息摘要算法有MD5算法和SHA-1算法及其大量的變體。它們可以用來保證數(shù)據(jù)的完整性,在網(wǎng)絡(luò)上發(fā)布文件時,常同時提供該文件的MD5值就是利用的消息摘要算法的這個特點,一旦該文件被篡改或者在網(wǎng)絡(luò)傳輸中出現(xiàn)數(shù)據(jù)錯誤,再對其進(jìn)行摘要運算就得不到相同的MD5值。
對數(shù)據(jù)進(jìn)行簽名是我們在網(wǎng)絡(luò)中最常見的安全操作。簽名有雙重作用,作用一就是保證數(shù)據(jù)的完整性,證明數(shù)據(jù)并非偽造,而且在傳輸?shù)倪^程中沒有被篡改,作用二就是防止數(shù)據(jù)的發(fā)布者否認(rèn)其發(fā)布了該數(shù)據(jù)。簽名同時使用了非對稱性加密算法和消息摘要算法,對一塊數(shù)據(jù)簽名時,會先對這塊數(shù)據(jù)進(jìn)行消息摘要運算生成一個摘要,然后對該摘要使用發(fā)布者的私鑰進(jìn)行加密。接收者接受這塊數(shù)據(jù)后,先使用發(fā)布者的公鑰進(jìn)行解密得到原數(shù)據(jù)的摘要,再對接收到的數(shù)據(jù)計算摘要,如果兩個摘要相同,則說明數(shù)據(jù)沒有被篡改。同時,因為發(fā)布者的私鑰是不公開的,只要接收者通過發(fā)布者的公鑰能成功對數(shù)據(jù)進(jìn)行解密,就說明該數(shù)據(jù)一定來源于該發(fā)布者,他再怎么抵賴也沒有用。
那么問題來了,怎么確定某公鑰一定是屬于某發(fā)布者的呢?這就需要證書了。證書由權(quán)威認(rèn)證機(jī)構(gòu)頒發(fā),其內(nèi)容包含證書所有者的標(biāo)識和它的公鑰,并由權(quán)威認(rèn)證機(jī)構(gòu)使用它的私鑰進(jìn)行簽名。信息的發(fā)布者通過在網(wǎng)絡(luò)上發(fā)布證書來公開它的公鑰,該證書由權(quán)威認(rèn)證機(jī)構(gòu)進(jìn)行簽名,認(rèn)證機(jī)構(gòu)也是通過發(fā)布它的證書來公開該機(jī)構(gòu)的公鑰,認(rèn)證機(jī)構(gòu)的證書由更權(quán)威的認(rèn)證機(jī)構(gòu)進(jìn)行簽名,這樣就形成了證書鏈。證書鏈最頂端的證書稱為根證書,根證書就只有自簽名了??傊?,要對網(wǎng)絡(luò)上傳播的內(nèi)容進(jìn)行簽名和認(rèn)證,就一定會用到證書。關(guān)于證書遵循的標(biāo)準(zhǔn),最流行的是 X.509,關(guān)于證書的具體內(nèi)容,網(wǎng)絡(luò)上一搜一大把,我這里就不講了。
在 Java 中也廣泛使用證書,例如,使用 jarsigner
命令對 jar 包進(jìn)行簽名和認(rèn)證。JDK 中創(chuàng)建和管理證書的工具是 keytool
。 keytool
是一個功能強大的安全工具,它不僅僅只是用來創(chuàng)建和管理證書,還可以用來創(chuàng)建和管理對稱性加密算法需要用到的密鑰,還可以用自己的證書給別人簽發(fā)證書(類似 CA 的工作),還可以導(dǎo)入別人發(fā)布的證書。 keytool
使用 keystore 存儲密鑰和證書,在一個 keystore 中可以存儲多個條目,訪問 keystore 和訪問 keystore 中的條目均需要密碼。
下面開始實戰(zhàn)。要進(jìn)行非對稱性加密,我們首先要有屬于自己的私鑰/公鑰對,這可以通過 keytool -genkeypairs -alias xxx
命令得到。創(chuàng)建密鑰對的時候, keytool
會在 keystore 中生成一個新的條目, -alias xxx
選項就是對該條目進(jìn)行命名。生成密鑰對之后,私鑰是以原始數(shù)據(jù)直接儲存在 keystore 中的,而公鑰是要發(fā)布出去的,所以它被封裝在一個 X.509 格式的自簽名證書中。換句話說,創(chuàng)建密鑰對的時候,同時就創(chuàng)建了一個自簽名的證書。
先將自己假想為一個認(rèn)證機(jī)構(gòu),或者說一個只對我自己簽發(fā)證書的私有認(rèn)證機(jī)構(gòu),我稱之為 MyCA,先為 MyCA 生成一個自簽名的根證書,使用的命令是 keytool -genkeypair -alias MyCA
,如下圖:
keytool -list
命令看一下,可以看到 keystore 中新增的 MyCA 條目。 如果給 keytool -list
命令增加 -v
選項,則可以看到更加詳細(xì)的內(nèi)容。這些內(nèi)容可以讓我們對 MyCA 的證書有更直觀的了解,如下圖:
然后,再為我自己生成一個密鑰對,使用命令 keytool -genkeypair -alias youxia
命令,按提示完成操作后,keystore 中就又多了一個 youxia 條目,如下圖:
使用 keytool -list -v -alias youxia
命令可以查看 youxia 的證書,它也是自簽名的,如下圖:
自簽名的證書可以使用,但是總不如認(rèn)證機(jī)構(gòu)頒發(fā)的證書權(quán)威。怎么樣讓 CA 為我們頒發(fā)證書呢?首先我們要向 CA 提交申請,提交申請的時候需要提交一份稱為 certificate request 的數(shù)據(jù)。我們可以通過 keytool -certreq
命令針對 keystore 中相應(yīng)的條目生成該數(shù)據(jù)。在這里,我想讓 CA 給 youxia 頒發(fā)證書,則使用 keytool -certreq -alias youxia
來生成 certificate request,我同時使用管道和 tee
命令讓生成的數(shù)據(jù)既顯示在控制臺中,又保存在文件 youxia.certreq
中,如下圖:
keytool -gencert -alias MyCA -infile youxia.certreq -outfile youxia.cer
,文件 youxia.cer
就是由 MyCA 頒發(fā)的證書。使用 keytool -printcert -v -file youxia.cer
命令可以查看該證書。 然后,申請者收到 CA 頒發(fā)的證書后,可以使用 keytool -importcert -alias youxia -file youxia.cer
將證書導(dǎo)入到 keystore 中。導(dǎo)入證書后,再使用 keytool -list -v -alias youxia
查看,會看到完整的證書鏈,如下圖:
作為管理工具,keytool 當(dāng)然提供導(dǎo)出證書的功能,使用 keytool -exportcert
命令即可。至此,我們已經(jīng)完全了解了生成密鑰對和證書的完整流程。關(guān)于 keytool 更詳細(xì)的參數(shù),請大家自己查看 keytool
的文檔吧。
keytool 的使用方法很簡單,重要的也就是 keytool -genkeypair
、keytool -gencert
、keytool -certreq
等命令,看到這些命令基本上就可以想到它們的功能。讓人稍稍有點疑惑的是, keytool -genkeypair
不僅僅是生成密鑰對,它會同時對公鑰進(jìn)行包裝生成自簽名的證書, keytool -gencert
并不是憑空生成證書,而是對 certificate request 進(jìn)行回復(fù)。理解這兩點,使用 keytool 就暢通無阻了。
(京山游俠于2015-04-22發(fā)布于博客園,轉(zhuǎn)載請注明出處。)