数字证书 - Java加密与安全
生活随笔
收集整理的這篇文章主要介紹了
数字证书 - Java加密与安全
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
數(shù)字證書我們?cè)谇懊婵吹搅艘恍┯?jì)算機(jī)密碼學(xué)的一些算法1. 摘要算法確保數(shù)據(jù)沒(méi)有被篡改2. 非對(duì)稱加密就是對(duì)數(shù)據(jù)進(jìn)行加解密3. 數(shù)據(jù)簽名可以確保數(shù)據(jù)完整性和抗否認(rèn)性而數(shù)字證書就是集合了多種密碼學(xué)算法,用于實(shí)現(xiàn)數(shù)據(jù)加解密,身份認(rèn)證,簽名等多種功能的一種網(wǎng)絡(luò)安全標(biāo)準(zhǔn)我們看數(shù)字證書:1. 首先實(shí)現(xiàn)了非對(duì)稱加密算法,可以對(duì)數(shù)據(jù)進(jìn)行加解密2. 然后他有簽名算法,能夠確保數(shù)據(jù)完整性和抗否認(rèn)性3. 最后通過(guò)摘要算法,確保證書本身沒(méi)有被篡改
package com.learn.securl;import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.util.Base64;import javax.crypto.Cipher;public class X509 {/*** 在這個(gè)類中我們定義一個(gè)privateKey* privateKey代表的是私鑰*/private final PrivateKey privateKey;/*** 和一個(gè)X509Certificate的一個(gè)變量* X509Certificate表示的是證書,公鑰,以及摘要的*/private final X509Certificate certificate;/*** 我們需要傳入keyStore和證書的名稱和password* 我們通過(guò)KeyStore的getKey方法傳入名稱和password* 就可以得到一個(gè)privateKey* 我們通過(guò)KeyStore的getCertificate方法傳入證書的名稱* 就可以得到一個(gè)X509Certificate的一個(gè)對(duì)象* @param ks* @param certName* @param password* @throws GeneralSecurityException*/public X509(KeyStore ks, String certName, String password) throws GeneralSecurityException{/*** 注意密碼用于獲得私鑰*/this.privateKey = (PrivateKey) ks.getKey(certName, password.toCharArray());/*** 獲得證書是不需要口令的*/this.certificate = (X509Certificate) ks.getCertificate(certName);}/*** 然后我們定義一個(gè)encrypt仿方法進(jìn)行加密* @param message* @return* @throws GeneralSecurityException*/public byte[] encrypt(byte[] message) throws GeneralSecurityException{/*** 在加密的時(shí)候我們首先通過(guò)Cipher.getInstance* 然后我們通過(guò)privateKey.getAlgorithm獲得加密算法*/Cipher cipher = Cipher.getInstance(this.privateKey.getAlgorithm());/*** 然后我們?cè)O(shè)置ENCRYPT_MODE并且傳入privateKey*/cipher.init(Cipher.ENCRYPT_MODE, this.privateKey);/*** 然后獲取密文*/return cipher.doFinal(message);}/*** 然后我們定義一個(gè)decrypt* @param data* @return* @throws GeneralSecurityException*/public byte[] decrypt(byte[] data) throws GeneralSecurityException{/*** 在解密的時(shí)候通過(guò)certificate對(duì)象getPublicKey就可以獲得公鑰publicKey*/PublicKey publicKey = this.certificate.getPublicKey();/*** 然后我們還是通過(guò)Cipher.getInstance獲得一個(gè)Cipher對(duì)象*/Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());/*** 設(shè)置為解密模式*/cipher.init(Cipher.DECRYPT_MODE, publicKey);/*** 然后傳入publicKey* 就可以正常的解密*/return cipher.doFinal(data);}/*** 我們?cè)俣x一個(gè)sign方法用于簽名* 傳入原始的Message* @param message* @return* @throws GeneralSecurityException*/public byte[] sign(byte[] message) throws GeneralSecurityException{/*** 然后通過(guò)Signature.getInstance* 通過(guò)certificate對(duì)象getSigAlgName獲得簽名算法*/Signature signature = Signature.getInstance(this.certificate.getSigAlgName());/*** 我們用privateKey進(jìn)行簽名*/signature.initSign(this.privateKey);signature.update(message);/*** 獲得簽名以后的數(shù)據(jù)*/return signature.sign();}/*** 我們?cè)俣x一個(gè)verify方法驗(yàn)證簽名* 需要傳入原始信息和簽名信息* 驗(yàn)證簽名的時(shí)候需要使用公鑰* 同時(shí)獲得的還有簽名的算法* @param message* @param sign* @return* @throws GeneralSecurityException*/public boolean verify(byte[] message, byte[] sign) throws GeneralSecurityException{Signature signature = Signature.getInstance(this.certificate.getSigAlgName());signature.initVerify(this.certificate);signature.update(message);return signature.verify(sign);}/*** 我們定義一個(gè)新的方法loadKeyStore* 用于加載一個(gè)KeyStore文件* 因?yàn)镴AVA的數(shù)字證書是存儲(chǔ)在KeyStore里面的* 我們需要指定一個(gè)KeyStore的文件* 打開(kāi)KeyStore用到的密碼* @param keyStoreFile* @param password* @return* @throws GeneralSecurityException* @throws IOException*/static KeyStore loadKeyStore(String keyStoreFile, String password) throws GeneralSecurityException, IOException{try(InputStream input = new BufferedInputStream(new FileInputStream(keyStoreFile))){/*** 我們通過(guò)KeyStore.getInstance得到一個(gè)KeyStore對(duì)象*/KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());/*** 通過(guò)KeyStore的load方法* 傳入一個(gè)inputStream就可以得到KeyStore對(duì)象*/ks.load(input, password.toCharArray());return ks;}}/*** 最后我們使用main方法使用數(shù)字證書以及加密和簽名,* 在執(zhí)行這個(gè)程序之前,* 首先我們要?jiǎng)?chuàng)建我們的數(shù)字證書* keytool -genkeypair -keyalg RSA -keysize 1024 * -sigalg SHA1withRSA -validity 36500 -alias mycert * -keystore my.keystore -dname “CN=test07, OU=sample, * O=sample, L=BJ, ST=BJ, C=CN” -keypass 123456 * -storepass 456789* genkeypair表示我們要生成一個(gè)數(shù)字證書* -keyalg RSA他的算法是RSA* -keysize 1024他的密鑰長(zhǎng)度是1024* -sigalg SHA1withRSA我們指定的算法長(zhǎng)度是SHA1withRSA* -validity 36500我們指定數(shù)字證書的有效期是36500* -alias mycert我們給這個(gè)證書寫一個(gè)名字叫做mycert* -keystore my.keystore同時(shí)我們指定了一個(gè)keystore的文件叫做my.keystore* “CN=test07, OU=sample, O=sample, L=BJ, ST=BJ, C=CN”* -keypass 123456然后我們用keypass指定證書的密碼123456* -storepass 456789我們用storepass指定store的密碼是456789* 緊接著我們要給證書指定CN OU這些屬性* 如果這個(gè)證書將來(lái)要用于網(wǎng)站* CN的屬性必須和網(wǎng)站的域名完全一致* keytool -list -keystore my.keystore -storepass 456789* 我們還可以通過(guò)keytool的命令查詢證書* 我們輸入命令然后回車* 我們就可以看到包含了一個(gè)證書mycert* 我們就可以看到在項(xiàng)目的根目錄中生成一個(gè)my.cert的一個(gè)文件* * 我們?cè)趫?zhí)行的時(shí)候可以看到* 我們?cè)趫?zhí)行證書得到加密以后的密文* 解密以后得到原始的明文* 我們對(duì)數(shù)字證書對(duì)原始的消息進(jìn)行簽名* 得到Base64表示的簽名* 最后我們用證書得到這個(gè)簽名結(jié)果為true* @param args* @throws GeneralSecurityException* @throws IOException*/public static void main(String[] args) throws GeneralSecurityException, IOException {byte[] message = "Hello, 使用X.509證書進(jìn)行加密和簽名!".getBytes();// 讀取KeyStore:/*** 首先我們需要讀取一個(gè)KeyStore* 然后傳入KeyStore的密碼* * 注意到我們用loadKeyStore的時(shí)候傳入了keyStore文件的密碼*/KeyStore ks = loadKeyStore("my.keystore", "456789");// 讀取證書:/*** 緊接著我們需要讀取一個(gè)X509證書* 并且傳入證書的密碼* 并且獲取他的私鑰* * 我們?cè)谧x取證書的時(shí)候傳入的是證書的密碼*/X509 x509 = new X509(ks, "mycert", "123456");// 加密:/*** 然后我們進(jìn)行加密*/byte[] encrypted = x509.encrypt(message);System.out.println("encrypted: " + Base64.getEncoder().encodeToString(encrypted));// 解密:byte[] decrypted = x509.decrypt(encrypted);System.out.println("decrypted: " + new String(decrypted, "UTF-8"));// 簽名:byte[] sign = x509.sign(message);System.out.println("sign: " + Base64.getEncoder().encodeToString(sign));// 驗(yàn)證簽名:boolean verified = x509.verify(message, sign);System.out.println("verify: " + verified);}
}
數(shù)字證書采用鏈?zhǔn)胶灻J(rèn)證,他的底層證書是Geo Trust 證書,然后由他簽發(fā)的GeoTrust SSL CA - G3證書,最后由mail.qq.com
我們最后來(lái)看一下數(shù)字證書的應(yīng)用:1.我們?cè)谏暇W(wǎng)的時(shí)候用到的https,這個(gè)協(xié)議實(shí)際上是http over ssl2. 在使用https的時(shí)候,服務(wù)器會(huì)發(fā)送證書給客戶端,這個(gè)證書包括公鑰,簽名,和CA證書3. 客戶端可以驗(yàn)證服務(wù)器端的證書是否有效,來(lái)確認(rèn)服務(wù)器的身份4. 然后客戶端使用證書加密一個(gè)隨機(jī)口令,發(fā)送給服務(wù)器端,采用的是公鑰加密5. 而服務(wù)器端解密獲得一個(gè)隨機(jī)口令,采用的是私鑰解密6. 雙方隨后就可以使用AES加密進(jìn)行通信,這個(gè)時(shí)候使用的是對(duì)稱加密
服務(wù)器發(fā)送的數(shù)字證書實(shí)際上是publicKey,就是公鑰,以及public的信息,比如摘要簽名等,服務(wù)器的私鑰永遠(yuǎn)保存在服務(wù)器端,不能泄露,所以數(shù)字證書實(shí)際上包含的是公鑰最后我們總結(jié)一下:1. 數(shù)字證書實(shí)際上就是集合了多種密碼學(xué)算法,用于實(shí)現(xiàn)數(shù)據(jù)加解密,身份認(rèn)證,簽名等多種功能的一種網(wǎng)絡(luò)安全標(biāo)準(zhǔn)2. 數(shù)字認(rèn)證采用的是一種鏈?zhǔn)胶灻墓芾?頂級(jí)的CA證書已經(jīng)內(nèi)置在操作系統(tǒng)中3. 常用的算法有MD5,SHA1,SHA256,RSA,DSA
?
總結(jié)
以上是生活随笔為你收集整理的数字证书 - Java加密与安全的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: DSA签名算法 - Java加密与安全
- 下一篇: Java内存结构与垃圾回收机制算法分析