【Http】加解密 生成 X.509格式,DER編碼,後綴名.cer 加密公鑰證書

在這裏插入圖片描述

1. 背景

因爲遇到了問題:參考 【Https】keytool 導入證書到 本地 Exception: Input not an X.509 certificate

然後就想查查這個怎麼解決搜到瞭如下博客:
加解密 生成 X.509格式,DER編碼,後綴名.cer。加密公鑰證書

這裏對這個博客進行一點補充

關於keyGenerator,KeyPairGenerator,SecretKeyFactory的解析
Java加密的常用的加密算法類型有三種

1單向加密:也就是不可逆的加密,例如MD5,SHA,HMAC

2對稱加密:也就是加密方和解密方利用同一個祕鑰對數據進行加密和解密,例如DES,PBE等等

3非對稱加密:非對稱加密分爲公鑰和祕鑰,二者是非對稱的,例如用私鑰加密的內容需要使用公鑰來解密,使用公鑰加密的內容需要用私鑰來解密,DSA,RSA…

而keyGenerator,KeyPairGenerator,SecretKeyFactory的三種使用方法剛好和這三種加密算法類型對上

keyGenerator:祕鑰生成器,也就是更具算法類型隨機生成一個祕鑰,例如HMAC,所以這個大部分用在非可逆的算法中

SecretKeyFactory:祕密祕鑰工廠,言外之意就是需要根據一個祕密(password)去生成一個祕鑰,例如DES,PBE,所以大部分使用在對稱加密中

KeyPairGenerator:祕鑰對生成器,也就是可以生成一對祕鑰,也就是公鑰和私鑰,所以大部分使用在非對稱加密中

public static void main(String[] args) throws Exception {
        
        byte[] msg = "test!中文".getBytes("UTF8"); // 待加解密的消息
    
        // 用證書的公鑰加密
        CertificateFactory cff = CertificateFactory.getInstance("X.509");
        FileInputStream fis1 = new FileInputStream("D:/test/zhongxin.cer"); // 證書文件
        Certificate cf = cff.generateCertificate(fis1);
        PublicKey pk1 = cf.getPublicKey(); // 得到證書文件攜帶的公鑰
        Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 定義算法:RSA
        c1.init(Cipher.ENCRYPT_MODE, pk1);
        byte[] msg1 = c1.doFinal(msg); // 加密後的數據
    
        // 用證書的私鑰解密 - 該私鑰存在生成該證書的密鑰庫中
        FileInputStream fis2 = new FileInputStream("D:/test/c-abc.keystore");
        KeyStore ks = KeyStore.getInstance("JKS"); // 加載證書庫
        char[] kspwd = "123456".toCharArray(); // 證書庫密碼
        char[] keypwd = "abcd1234".toCharArray(); // 證書密碼
        ks.load(fis2, kspwd); // 加載證書
        PrivateKey pk2 = (PrivateKey) ks.getKey("zhongxin", keypwd); // 獲取證書私鑰
        fis2.close();
        Cipher c2 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        c2.init(Cipher.DECRYPT_MODE, pk2);
        byte[] msg2 = c2.doFinal(msg1); // 解密後的數據
    
        System.out.println(new String(msg2, "UTF8")); // 將解密數據轉爲字符串
        String aaa=Base64.getEncoder().encodeToString(pk2.getEncoded());
        System.out.println(aaa);
        PKCS8EncodedKeySpec spec =new PKCS8EncodedKeySpec(Base64.getDecoder().decode(aaa)); 
        PrivateKey priva = KeyFactory.getInstance("RSA").generatePrivate(spec); 
       
        
        Cipher cc2 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cc2.init(Cipher.DECRYPT_MODE, priva);
        byte[] msg22 = cc2.doFinal(msg1); // 解密後的數據
    
        System.out.println(new String(msg22, "UTF8")); // 將解密數據轉爲字符串
        
        //aaa();
    }

一.keytool的概念

keytool 是個密鑰和證書管理工具。它使用戶能夠管理自己的公鑰/私鑰對及相關證書,用於(通過數字簽名)自我認證(用戶向別的用戶/服務認證自己)或數據完整性以及認證服務。在JDK 1.4以後的版本中都包含了這一工具,它的位置爲%JAVA_HOME%\bin\keytool.exe,如下圖所示:

[lcc@lcc ~/soft/ssl]$ cd $JAVA_HOME
[lcc@lcc /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home]$ cd bin/
[lcc@lcc /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/bin]$ ll | grep tool
-rwxr-xr-x   1 root  wheel  113424 12 11  2019 keytool*
-rwxr-xr-x   1 root  wheel  113424 12 11  2019 policytool*
-rwxr-xr-x   1 root  wheel  113424 12 11  2019 servertool*
[lcc@lcc /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/bin]$

三.創建證書

實戰命令

mac下實戰

# 1.生成私鑰
lcc@lcc ~/soft/ssl]$ keytool -genkey -alias aliasName -keyalg RSA -keysize 1024 -keypass 112233 -validity 1095 -keystore test1.ks -storepass 123456
您的名字與姓氏是什麼?
  [Unknown]:  lcc
您的組織單位名稱是什麼?
  [Unknown]:  lcc
您的組織名稱是什麼?
  [Unknown]:  lcc
您所在的城市或區域名稱是什麼?
  [Unknown]:  lcc
您所在的省//自治區名稱是什麼?
  [Unknown]:  lcc
該單位的雙字母國家/地區代碼是什麼?
  [Unknown]:  lcc
CN=lcc, OU=lcc, O=lcc, L=lcc, ST=lcc, C=lcc是否正確?
  []:  Y


Warning:
JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore test1.ks -destkeystore test1.ks -deststoretype pkcs12" 遷移到行業標準格式 PKCS12。


2.根據生成的私鑰導出公鑰
[lcc@lcc ~/soft/ssl]$ keytool -export -alias aliasName -keystore test1.ks -file test1.cer -storepass 123456
存儲在文件 <test1.cer> 中的證書

Warning:
JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore test1.ks -destkeystore test1.ks -deststoretype pkcs12" 遷移到行業標準格式 PKCS12。


3.查看證書
[lcc@lcc ~/soft/ssl]$ keytool -printcert -file /data/test1.cer
keytool 錯誤: java.io.FileNotFoundException: /data/test1.cer (No such file or directory)
[lcc@lcc ~/soft/ssl]$ keytool -printcert -file ./test1.cer
所有者: CN=lcc, OU=lcc, O=lcc, L=lcc, ST=lcc, C=lcc
發佈者: CN=lcc, OU=lcc, O=lcc, L=lcc, ST=lcc, C=lcc
序列號: 6d83f199
有效期爲 Tue Jul 07 18:38:18 CST 2020 至 Fri Jul 07 18:38:18 CST 2023
證書指紋:
	 MD5:  0E:DA:99:5F:6C:CF:09:C0:D8:F0:53:1F:2D:C6:41:1E
	 SHA1: D4:0A:35:9A:24:51:76:01:ED:8B:41:2F:41:C4:D4:16:55:56:10:9B
	 SHA256: B9:27:66:7E:9F:B6:E9:C0:68:74:F5:00:EE:51:C3:42:E0:22:C9:F4:EB:D5:BC:2F:8A:7B:B1:E0:F3:6B:22:37
簽名算法名稱: SHA256withRSA
主體公共密鑰算法: 1024 位 RSA 密鑰
版本: 3

擴展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 26 3D 39 52 0B 40 AE 32   99 9A FA 81 0A C9 64 1C  &=9R.@.2......d.
0010: B8 0E F3 83                                        ....
]
]



4.導入公鑰證書
[lcc@lcc ~/soft/ssl]$ keytool -import -file ./test1.cer -keystore cacerts -alias server
輸入密鑰庫口令: 這裏特別注意 mac的密碼是 123456 上面你設置的,winowds下爲 changeit
再次輸入新口令:
所有者: CN=lcc, OU=lcc, O=lcc, L=lcc, ST=lcc, C=lcc
發佈者: CN=lcc, OU=lcc, O=lcc, L=lcc, ST=lcc, C=lcc
序列號: 6d83f199
有效期爲 Tue Jul 07 18:38:18 CST 2020 至 Fri Jul 07 18:38:18 CST 2023
證書指紋:
	 MD5:  0E:DA:99:5F:6C:CF:09:C0:D8:F0:53:1F:2D:C6:41:1E
	 SHA1: D4:0A:35:9A:24:51:76:01:ED:8B:41:2F:41:C4:D4:16:55:56:10:9B
	 SHA256: B9:27:66:7E:9F:B6:E9:C0:68:74:F5:00:EE:51:C3:42:E0:22:C9:F4:EB:D5:BC:2F:8A:7B:B1:E0:F3:6B:22:37
簽名算法名稱: SHA256withRSA
主體公共密鑰算法: 1024 位 RSA 密鑰
版本: 3

擴展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 26 3D 39 52 0B 40 AE 32   99 9A FA 81 0A C9 64 1C  &=9R.@.2......d.
0010: B8 0E F3 83                                        ....
]
]

是否信任此證書? []:  y
證書已添加到密鑰庫中

window下密碼參考:https://www.jianshu.com/p/8bbef4a17d38

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章