與計(jì)費(fèi)系統(tǒng)打交道,少不了用到加密/解密實(shí)現(xiàn)。為了安全起見,通過非對稱加密交換對稱加密密鑰更是不可或缺。那么需要通過什么載體傳遞非對稱算法公鑰/私鑰信息?數(shù)字證書是公鑰的載體,而密鑰庫可以包含公鑰、私鑰信息。
JKS和PKCS#12都是比較常用的兩種密鑰庫格式/標(biāo)準(zhǔn)。對于前者,搞Java開發(fā),尤其是接觸過HTTPS平臺的朋友,并不陌生。JKS文件(通常為*.jks或*.keystore,擴(kuò)展名無關(guān))可以通過Java原生工具——KeyTool生成;而后者PKCS#12文件(通常為*.p12或*.pfx,意味個人信息交換文件),則是通過更為常用的OpenSSL工具產(chǎn)生。
當(dāng)然,這兩者之間是可以通過導(dǎo)入/導(dǎo)出的方式進(jìn)行轉(zhuǎn)換的!當(dāng)然,這種轉(zhuǎn)換需要通過KeyTool工具進(jìn)行!
回歸正題,計(jì)費(fèi)同事遇到一個難題:合作方交給他們一個*.pfx文件,需要他們從中提取密鑰,然后進(jìn)行加密交互。其實(shí),通過Java直接操作密鑰庫文件(或個人信息交換文件)對于一般Java開發(fā)人員來說,這都是個冷門。不接觸數(shù)字安全,根本不知所云。況且,Java原生的密鑰庫文件格式為JKS,如何操作*.pfx文件?密鑰庫操作需要獲知密鑰庫別名,*.pfx別名是什么?!這些難題都留給了我,當(dāng)然,我欣然接受并回報碩果!
方案:
先看可是轉(zhuǎn)換:
-importkeystore導(dǎo)入密鑰庫,通過格式設(shè)定,我們可以將PKCS#12文件轉(zhuǎn)換為JKS格式。
-v顯示詳情
-srckeystore源密鑰庫,這里是zlex.pfx
-srcstoretype源密鑰庫格式,這里為pkcs12
-srcstorepass源密鑰庫密碼,這里為123456
-destkeystore目標(biāo)密鑰庫,這里為zlex.keystore
-deststoretype目標(biāo)密鑰庫格式,這里為jks,默認(rèn)值也如此
-deststorepass目標(biāo)密鑰庫密碼,這里為123456
通過這個操作,我們能夠獲得所需的密鑰庫文件zlex.keystore。
這時,我們已經(jīng)獲得了密鑰庫文件,只要確定對應(yīng)的別名信息,就可以提取公鑰/私鑰,以及數(shù)字證書,進(jìn)行加密交互了!
-list列舉密鑰庫
-keystore密鑰庫,這里是zlex.keystore
-storepass密鑰庫密碼,這里是123456
-v顯示詳情
這里需要細(xì)致觀察一下別名信息?。?!就是紅框中的數(shù)字1?。?!
經(jīng)過我多次嘗試,將PKCS#12格式的密鑰庫轉(zhuǎn)化為JKS格式時,其別名一律為“1”!也就是說,我們完全可以不進(jìn)行密鑰庫轉(zhuǎn)換,也能獲得公鑰/私鑰。
現(xiàn)在,我們把證書導(dǎo)出!
-exportcert導(dǎo)出證書
-alias別名,這里是1
-keystore密鑰庫,這里是zlex.keystore
-file證書文件,這里是zlex.crt
-storepass密鑰庫密碼,這里是123456
現(xiàn)在證書也導(dǎo)出了,我們可以提取公鑰/私鑰,進(jìn)行加密/解密,簽名/驗(yàn)證操作了!當(dāng)然,即便沒有證書,我們也能夠通過密鑰庫(JKS格式)文件獲得證書,以及公鑰/私鑰、簽名算法等。
補(bǔ)充代碼, 其實(shí)就是對Java加密技術(shù)(八)的修改!
相信上述代碼已經(jīng)幫朋友們解決了相當(dāng)多的問題!
給出測試類:
第一個測試方法,用于提取公鑰/私鑰進(jìn)行加密/解密操作。
第二個測試方法,用于提取簽名算法進(jìn)行簽名/驗(yàn)證操作。
OK,任務(wù)完成,密鑰成功提取,剩下的都是代碼基本功了!
JKS和PKCS#12都是比較常用的兩種密鑰庫格式/標(biāo)準(zhǔn)。對于前者,搞Java開發(fā),尤其是接觸過HTTPS平臺的朋友,并不陌生。JKS文件(通常為*.jks或*.keystore,擴(kuò)展名無關(guān))可以通過Java原生工具——KeyTool生成;而后者PKCS#12文件(通常為*.p12或*.pfx,意味個人信息交換文件),則是通過更為常用的OpenSSL工具產(chǎn)生。
當(dāng)然,這兩者之間是可以通過導(dǎo)入/導(dǎo)出的方式進(jìn)行轉(zhuǎn)換的!當(dāng)然,這種轉(zhuǎn)換需要通過KeyTool工具進(jìn)行!
回歸正題,計(jì)費(fèi)同事遇到一個難題:合作方交給他們一個*.pfx文件,需要他們從中提取密鑰,然后進(jìn)行加密交互。其實(shí),通過Java直接操作密鑰庫文件(或個人信息交換文件)對于一般Java開發(fā)人員來說,這都是個冷門。不接觸數(shù)字安全,根本不知所云。況且,Java原生的密鑰庫文件格式為JKS,如何操作*.pfx文件?密鑰庫操作需要獲知密鑰庫別名,*.pfx別名是什么?!這些難題都留給了我,當(dāng)然,我欣然接受并回報碩果!
方案:
- 通過keytool密鑰庫導(dǎo)入命令importkeystore,將密鑰庫格式由PKCS#12轉(zhuǎn)換為JKS。
- 檢索新生成的密鑰庫文件,提取別名信息。
- 由密鑰庫文件導(dǎo)出數(shù)字證書(這里將用到別名)。
- 通過代碼提取公鑰/私鑰、簽名算法等
先看可是轉(zhuǎn)換:
- echo 格式轉(zhuǎn)換
- keytool -importkeystore -v -srckeystore zlex.pfx -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore zlex.keystore -deststoretype jks -deststorepass 123456
echo 格式轉(zhuǎn)換keytool -importkeystore -v -srckeystore zlex.pfx -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore zlex.keystore -deststoretype jks -deststorepass 123456
-importkeystore導(dǎo)入密鑰庫,通過格式設(shè)定,我們可以將PKCS#12文件轉(zhuǎn)換為JKS格式。
-v顯示詳情
-srckeystore源密鑰庫,這里是zlex.pfx
-srcstoretype源密鑰庫格式,這里為pkcs12
-srcstorepass源密鑰庫密碼,這里為123456
-destkeystore目標(biāo)密鑰庫,這里為zlex.keystore
-deststoretype目標(biāo)密鑰庫格式,這里為jks,默認(rèn)值也如此
-deststorepass目標(biāo)密鑰庫密碼,這里為123456
通過這個操作,我們能夠獲得所需的密鑰庫文件zlex.keystore。

這時,我們已經(jīng)獲得了密鑰庫文件,只要確定對應(yīng)的別名信息,就可以提取公鑰/私鑰,以及數(shù)字證書,進(jìn)行加密交互了!

- echo 查看證書
- keytool -list -keystore zlex.keystore -storepass 123456 -v
echo 查看證書keytool -list -keystore zlex.keystore -storepass 123456 -v
-list列舉密鑰庫
-keystore密鑰庫,這里是zlex.keystore
-storepass密鑰庫密碼,這里是123456
-v顯示詳情

這里需要細(xì)致觀察一下別名信息?。?!就是紅框中的數(shù)字1?。?!
經(jīng)過我多次嘗試,將PKCS#12格式的密鑰庫轉(zhuǎn)化為JKS格式時,其別名一律為“1”!也就是說,我們完全可以不進(jìn)行密鑰庫轉(zhuǎn)換,也能獲得公鑰/私鑰。
現(xiàn)在,我們把證書導(dǎo)出!
- echo 導(dǎo)出證書
- keytool -exportcert -alias 1 -keystore zlex.keystore -file zlex.crt -storepass 123456
echo 導(dǎo)出證書keytool -exportcert -alias 1 -keystore zlex.keystore -file zlex.crt -storepass 123456
-exportcert導(dǎo)出證書
-alias別名,這里是1
-keystore密鑰庫,這里是zlex.keystore
-file證書文件,這里是zlex.crt
-storepass密鑰庫密碼,這里是123456

現(xiàn)在證書也導(dǎo)出了,我們可以提取公鑰/私鑰,進(jìn)行加密/解密,簽名/驗(yàn)證操作了!當(dāng)然,即便沒有證書,我們也能夠通過密鑰庫(JKS格式)文件獲得證書,以及公鑰/私鑰、簽名算法等。
補(bǔ)充代碼, 其實(shí)就是對Java加密技術(shù)(八)的修改!

- /**
- * 2010-8-11
- */
- package org.zlex.pfx;
- import java.io.FileInputStream;
- import java.security.KeyStore;
- import java.security.PrivateKey;
- import java.security.PublicKey;
- import java.security.Signature;
- import java.security.cert.Certificate;
- import java.security.cert.CertificateFactory;
- import java.security.cert.X509Certificate;
- import java.util.Date;
- import javax.crypto.Cipher;
- /**
- * 證書操作類
- *
- * @author <a href="mailto:zlex.dongliang@gmail.com">梁棟</a>
- * @since 1.0
- */
- public class CertificateCoder {
- /**
- * Java密鑰庫(Java Key Store,JKS)KEY_STORE
- */
- public static final String KEY_STORE = "JKS";
- public static final String X509 = "X.509";
- /**
- * 由 KeyStore獲得私鑰
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- private static PrivateKey getPrivateKey(String keyStorePath, String alias,
- String password) throws Exception {
- KeyStore ks = getKeyStore(keyStorePath, password);
- PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());
- return key;
- }
- /**
- * 由 Certificate獲得公鑰
- *
- * @param certificatePath
- * @return
- * @throws Exception
- */
- private static PublicKey getPublicKey(String certificatePath)
- throws Exception {
- Certificate certificate = getCertificate(certificatePath);
- PublicKey key = certificate.getPublicKey();
- return key;
- }
- /**
- * 獲得Certificate
- *
- * @param certificatePath
- * @return
- * @throws Exception
- */
- private static Certificate getCertificate(String certificatePath)
- throws Exception {
- CertificateFactory certificateFactory = CertificateFactory
- .getInstance(X509);
- FileInputStream in = new FileInputStream(certificatePath);
- Certificate certificate = certificateFactory.generateCertificate(in);
- in.close();
- return certificate;
- }
- /**
- * 獲得Certificate
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- private static Certificate getCertificate(String keyStorePath,
- String alias, String password) throws Exception {
- KeyStore ks = getKeyStore(keyStorePath, password);
- Certificate certificate = ks.getCertificate(alias);
- return certificate;
- }
- /**
- * 獲得KeyStore
- *
- * @param keyStorePath
- * @param password
- * @return
- * @throws Exception
- */
- private static KeyStore getKeyStore(String keyStorePath, String password)
- throws Exception {
- FileInputStream is = new FileInputStream(keyStorePath);
- KeyStore ks = KeyStore.getInstance(KEY_STORE);
- ks.load(is, password.toCharArray());
- is.close();
- return ks;
- }
- /**
- * 私鑰加密
- *
- * @param data
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath,
- String alias, String password) throws Exception {
- // 取得私鑰
- PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
- // 對數(shù)據(jù)加密
- Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
- cipher.init(Cipher.ENCRYPT_MODE, privateKey);
- return cipher.doFinal(data);
- }
- /**
- * 私鑰解密
- *
- * @param data
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- * @throws Exception
- */
- public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath,
- String alias, String password) throws Exception {
- // 取得私鑰
- PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);
- // 對數(shù)據(jù)加密
- Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
- return cipher.doFinal(data);
- }
- /**
- * 公鑰加密
- *
- * @param data
- * @param certificatePath
- * @return
- * @throws Exception
- */
- public static byte[] encryptByPublicKey(byte[] data, String certificatePath)
- throws Exception {
- // 取得公鑰
- PublicKey publicKey = getPublicKey(certificatePath);
- // 對數(shù)據(jù)加密
- Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
- return cipher.doFinal(data);
- }
- /**
- * 公鑰解密
- *
- * @param data
- * @param certificatePath
- * @return
- * @throws Exception
- */
- public static byte[] decryptByPublicKey(byte[] data, String certificatePath)
- throws Exception {
- // 取得公鑰
- PublicKey publicKey = getPublicKey(certificatePath);
- // 對數(shù)據(jù)加密
- Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
- cipher.init(Cipher.DECRYPT_MODE, publicKey);
- return cipher.doFinal(data);
- }
- /**
- * 驗(yàn)證Certificate
- *
- * @param certificatePath
- * @return
- */
- public static boolean verifyCertificate(String certificatePath) {
- return verifyCertificate(new Date(), certificatePath);
- }
- /**
- * 驗(yàn)證Certificate是否過期或無效
- *
- * @param date
- * @param certificatePath
- * @return
- */
- public static boolean verifyCertificate(Date date, String certificatePath) {
- boolean status = true;
- try {
- // 取得證書
- Certificate certificate = getCertificate(certificatePath);
- // 驗(yàn)證證書是否過期或無效
- status = verifyCertificate(date, certificate);
- } catch (Exception e) {
- status = false;
- }
- return status;
- }
- /**
- * 驗(yàn)證證書是否過期或無效
- *
- * @param date
- * @param certificate
- * @return
- */
- private static boolean verifyCertificate(Date date, Certificate certificate) {
- boolean status = true;
- try {
- X509Certificate x509Certificate = (X509Certificate) certificate;
- x509Certificate.checkValidity(date);
- } catch (Exception e) {
- status = false;
- }
- return status;
- }
- /**
- * 簽名
- *
- * @param keyStorePath
- * @param alias
- * @param password
- *
- * @return
- * @throws Exception
- */
- public static byte[] sign(byte[] sign, String keyStorePath, String alias,
- String password) throws Exception {
- // 獲得證書
- X509Certificate x509Certificate = (X509Certificate) getCertificate(
- keyStorePath, alias, password);
- // 獲取私鑰
- KeyStore ks = getKeyStore(keyStorePath, password);
- // 取得私鑰
- PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password
- .toCharArray());
- // 構(gòu)建簽名
- Signature signature = Signature.getInstance(x509Certificate
- .getSigAlgName());
- signature.initSign(privateKey);
- signature.update(sign);
- return signature.sign();
- }
- /**
- * 驗(yàn)證簽名
- *
- * @param data
- * @param sign
- * @param certificatePath
- * @return
- * @throws Exception
- */
- public static boolean verify(byte[] data, byte[] sign,
- String certificatePath) throws Exception {
- // 獲得證書
- X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);
- // 獲得公鑰
- PublicKey publicKey = x509Certificate.getPublicKey();
- // 構(gòu)建簽名
- Signature signature = Signature.getInstance(x509Certificate
- .getSigAlgName());
- signature.initVerify(publicKey);
- signature.update(data);
- return signature.verify(sign);
- }
- /**
- * 驗(yàn)證Certificate
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- */
- public static boolean verifyCertificate(Date date, String keyStorePath,
- String alias, String password) {
- boolean status = true;
- try {
- Certificate certificate = getCertificate(keyStorePath, alias,
- password);
- status = verifyCertificate(date, certificate);
- } catch (Exception e) {
- status = false;
- }
- return status;
- }
- /**
- * 驗(yàn)證Certificate
- *
- * @param keyStorePath
- * @param alias
- * @param password
- * @return
- */
- public static boolean verifyCertificate(String keyStorePath, String alias,
- String password) {
- return verifyCertificate(new Date(), keyStorePath, alias, password);
- }
- }
/*** 2010-8-11*/package org.zlex.pfx;import java.io.FileInputStream;import java.security.KeyStore;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.cert.Certificate;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import java.util.Date;import javax.crypto.Cipher;/*** 證書操作類** @author <a href="mailto:zlex.dongliang@gmail.com">梁棟</a>* @since 1.0*/public class CertificateCoder {/*** Java密鑰庫(Java Key Store,JKS)KEY_STORE*/public static final String KEY_STORE = "JKS";public static final String X509 = "X.509";/*** 由 KeyStore獲得私鑰** @param keyStorePath* @param alias* @param password* @return* @throws Exception*/private static PrivateKey getPrivateKey(String keyStorePath, String alias,String password) throws Exception {KeyStore ks = getKeyStore(keyStorePath, password);PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());return key;}/*** 由 Certificate獲得公鑰** @param certificatePath* @return* @throws Exception*/private static PublicKey getPublicKey(String certificatePath)throws Exception {Certificate certificate = getCertificate(certificatePath);PublicKey key = certificate.getPublicKey();return key;}/*** 獲得Certificate** @param certificatePath* @return* @throws Exception*/private static Certificate getCertificate(String certificatePath)throws Exception {CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);FileInputStream in = new FileInputStream(certificatePath);Certificate certificate = certificateFactory.generateCertificate(in);in.close();return certificate;}/*** 獲得Certificate** @param keyStorePath* @param alias* @param password* @return* @throws Exception*/private static Certificate getCertificate(String keyStorePath,String alias, String password) throws Exception {KeyStore ks = getKeyStore(keyStorePath, password);Certificate certificate = ks.getCertificate(alias);return certificate;}/*** 獲得KeyStore** @param keyStorePath* @param password* @return* @throws Exception*/private static KeyStore getKeyStore(String keyStorePath, String password)throws Exception {FileInputStream is = new FileInputStream(keyStorePath);KeyStore ks = KeyStore.getInstance(KEY_STORE);ks.load(is, password.toCharArray());is.close();return ks;}/*** 私鑰加密** @param data* @param keyStorePath* @param alias* @param password* @return* @throws Exception*/public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath,String alias, String password) throws Exception {// 取得私鑰PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);// 對數(shù)據(jù)加密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 私鑰解密** @param data* @param keyStorePath* @param alias* @param password* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath,String alias, String password) throws Exception {// 取得私鑰PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password);// 對數(shù)據(jù)加密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);}/*** 公鑰加密** @param data* @param certificatePath* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, String certificatePath)throws Exception {// 取得公鑰PublicKey publicKey = getPublicKey(certificatePath);// 對數(shù)據(jù)加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 公鑰解密** @param data* @param certificatePath* @return* @throws Exception*/public static byte[] decryptByPublicKey(byte[] data, String certificatePath)throws Exception {// 取得公鑰PublicKey publicKey = getPublicKey(certificatePath);// 對數(shù)據(jù)加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);}/*** 驗(yàn)證Certificate** @param certificatePath* @return*/public static boolean verifyCertificate(String certificatePath) {return verifyCertificate(new Date(), certificatePath);}/*** 驗(yàn)證Certificate是否過期或無效** @param date* @param certificatePath* @return*/public static boolean verifyCertificate(Date date, String certificatePath) {boolean status = true;try {// 取得證書Certificate certificate = getCertificate(certificatePath);// 驗(yàn)證證書是否過期或無效status = verifyCertificate(date, certificate);} catch (Exception e) {status = false;}return status;}/*** 驗(yàn)證證書是否過期或無效** @param date* @param certificate* @return*/private static boolean verifyCertificate(Date date, Certificate certificate) {boolean status = true;try {X509Certificate x509Certificate = (X509Certificate) certificate;x509Certificate.checkValidity(date);} catch (Exception e) {status = false;}return status;}/*** 簽名** @param keyStorePath* @param alias* @param password** @return* @throws Exception*/public static byte[] sign(byte[] sign, String keyStorePath, String alias,String password) throws Exception {// 獲得證書X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password);// 獲取私鑰KeyStore ks = getKeyStore(keyStorePath, password);// 取得私鑰PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password.toCharArray());// 構(gòu)建簽名Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());signature.initSign(privateKey);signature.update(sign);return signature.sign();}/*** 驗(yàn)證簽名** @param data* @param sign* @param certificatePath* @return* @throws Exception*/public static boolean verify(byte[] data, byte[] sign,String certificatePath) throws Exception {// 獲得證書X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);// 獲得公鑰PublicKey publicKey = x509Certificate.getPublicKey();// 構(gòu)建簽名Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());signature.initVerify(publicKey);signature.update(data);return signature.verify(sign);}/*** 驗(yàn)證Certificate** @param keyStorePath* @param alias* @param password* @return*/public static boolean verifyCertificate(Date date, String keyStorePath,String alias, String password) {boolean status = true;try {Certificate certificate = getCertificate(keyStorePath, alias,password);status = verifyCertificate(date, certificate);} catch (Exception e) {status = false;}return status;}/*** 驗(yàn)證Certificate** @param keyStorePath* @param alias* @param password* @return*/public static boolean verifyCertificate(String keyStorePath, String alias,String password) {return verifyCertificate(new Date(), keyStorePath, alias, password);}}
相信上述代碼已經(jīng)幫朋友們解決了相當(dāng)多的問題!

給出測試類:
- package org.zlex.pfx;
- import static org.junit.Assert.*;
- import org.apache.commons.codec.binary.Hex;
- import org.junit.Test;
- /**
- * 證書操作驗(yàn)證類
- *
- * @author <a href="mailto:zlex.dongliang@gmail.com">梁棟</a>
- * @version 1.0
- * @since 1.0
- */
- public class CertificateCoderTest {
- private String password = "123456";
- private String alias = "1";
- private String certificatePath = "zlex.crt";
- private String keyStorePath = "zlex.keystore";
- @Test
- public void test() throws Exception {
- System.err.println("公鑰加密——私鑰解密");
- String inputStr = "Ceritifcate";
- byte[] data = inputStr.getBytes();
- byte[] encrypt = CertificateCoder.encryptByPublicKey(data,
- certificatePath);
- byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt,
- keyStorePath, alias, password);
- String outputStr = new String(decrypt);
- System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
- // 驗(yàn)證數(shù)據(jù)一致
- assertArrayEquals(data, decrypt);
- // 驗(yàn)證證書有效
- assertTrue(CertificateCoder.verifyCertificate(certificatePath));
- }
- @Test
- public void testSign() throws Exception {
- System.err.println("私鑰加密——公鑰解密");
- String inputStr = "sign";
- byte[] data = inputStr.getBytes();
- byte[] encodedData = CertificateCoder.encryptByPrivateKey(data,
- keyStorePath, alias, password);
- byte[] decodedData = CertificateCoder.decryptByPublicKey(encodedData,
- certificatePath);
- String outputStr = new String(decodedData);
- System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);
- assertEquals(inputStr, outputStr);
- System.err.println("私鑰簽名——公鑰驗(yàn)證簽名");
- // 產(chǎn)生簽名
- byte[] sign = CertificateCoder.sign(encodedData, keyStorePath, alias,
- password);
- System.err.println("簽名:\r" + Hex.encodeHexString(sign));
- // 驗(yàn)證簽名
- boolean status = CertificateCoder.verify(encodedData, sign,
- certificatePath);
- System.err.println("狀態(tài):\r" + status);
- assertTrue(status);
- }
- }
package org.zlex.pfx;import static org.junit.Assert.*;import org.apache.commons.codec.binary.Hex;import org.junit.Test;/*** 證書操作驗(yàn)證類** @author <a href="mailto:zlex.dongliang@gmail.com">梁棟</a>* @version 1.0* @since 1.0*/public class CertificateCoderTest {private String password = "123456";private String alias = "1";private String certificatePath = "zlex.crt";private String keyStorePath = "zlex.keystore";@Testpublic void test() throws Exception {System.err.println("公鑰加密——私鑰解密");String inputStr = "Ceritifcate";byte[] data = inputStr.getBytes();byte[] encrypt = CertificateCoder.encryptByPublicKey(data,certificatePath);byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt,keyStorePath, alias, password);String outputStr = new String(decrypt);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);// 驗(yàn)證數(shù)據(jù)一致assertArrayEquals(data, decrypt);// 驗(yàn)證證書有效assertTrue(CertificateCoder.verifyCertificate(certificatePath));}@Testpublic void testSign() throws Exception {System.err.println("私鑰加密——公鑰解密");String inputStr = "sign";byte[] data = inputStr.getBytes();byte[] encodedData = CertificateCoder.encryptByPrivateKey(data,keyStorePath, alias, password);byte[] decodedData = CertificateCoder.decryptByPublicKey(encodedData,certificatePath);String outputStr = new String(decodedData);System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);assertEquals(inputStr, outputStr);System.err.println("私鑰簽名——公鑰驗(yàn)證簽名");// 產(chǎn)生簽名byte[] sign = CertificateCoder.sign(encodedData, keyStorePath, alias,password);System.err.println("簽名:\r" + Hex.encodeHexString(sign));// 驗(yàn)證簽名boolean status = CertificateCoder.verify(encodedData, sign,certificatePath);System.err.println("狀態(tài):\r" + status);assertTrue(status);}}
第一個測試方法,用于提取公鑰/私鑰進(jìn)行加密/解密操作。
第二個測試方法,用于提取簽名算法進(jìn)行簽名/驗(yàn)證操作。

OK,任務(wù)完成,密鑰成功提取,剩下的都是代碼基本功了!

cer證書文件本身就是算法以及公鑰的載體,而私鑰就需要私密保存,不對外公布了!