前言
本文使用語言爲Kotlin,讀者若有Java基礎的也能看得懂 或者點擊此處去學習下Kotlin
需求
需求是這樣的,現在需要爲客戶建立一個KeyStore
不依靠openssl等命令行,使用代碼進行對Keystore的增刪改查
理解KeyStore相關API
文檔是JDK11SE文檔的一部分(需要有一定英文閱讀能力)
參考官方在線文檔或CSDN下載文檔pdf
圖說代碼(新建)
先對KeyStore有個總體印象,可以作爲拓展自行去了解,
本文專注於API實戰,不過多介紹,能提供的相關資料會留在結尾
如圖KeyStore管理了三類Key:單祕鑰、祕鑰對(私鑰+證書)、單證書
Type 類型 常見PKCS12 JKS
provider 提供者 可爲空
File 完整文件名
Parameter 用於保護KeyStore諸如訪問密碼、保護算法
# java.security.KeyStore.Builder 的構建方法 用於創建一個全新的KeyStore
public static Builder newInstance(String type, Provider provider, ProtectionParameter protection)
#實現了在桌面新建一個文件名newStore.p12 使用 PKCS12標準的 祕鑰庫
const val PATH = "C:\\Users\\Administrator\\Desktop\\newStore.p12"
const val PASSWORD = "123456"
fun main(){
val keyStore = KeyStore.Builder.newInstance("PKCS12",null,
KeyStore.PasswordProtection(null)).keyStore
keyStore.store(File(PATH).outputStream(),
PASSWORD.toCharArray())
}
用KeyStore Explorer打開輸入密碼後,看到一個空的KeyStore就創建好了
刪改查篇
讀取
導入前需要對上文創建的KeyStore進行讀取
課本翻到 Key Management
public final void load(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException
導入證書
本文不贅述證書相關API,可以去查看我其他文章(如果有) 補習入口
public final void setCertificateEntry(String alias, Certificate cert)
throws KeyStoreException
#對文件的讀取、加入一份證書保存
const val PATH = "C:\\Users\\Administrator\\Desktop\\newStore.p12"
const val PASSWORD = "123456"
fun main(){
val keyStore = KeyStore.getInstance("PKCS12").apply {
load(File(PATH).inputStream(),PASSWORD.toCharArray())
}
keyStore.setCertificateEntry("client",getCert())//證書生成此處不說明
keyStore.store(File(PATH).outputStream(),PASSWORD.toCharArray())
}
導入單祕鑰
知識補充:上圖說明了各個Entry的對應關係
看到那個小鎖了嗎?沒錯!還能爲祕鑰設密碼。
#放入Entry就看這個方法了
public final void setEntry(String alias, Entry entry,
ProtectionParameter protParam)
#當然,PasswordProtection 就對應了密碼保護 可以於Entry一起放入KeyStore
public static class Passwo·rdProtection implements
ProtectionParameter
# 爲之前的KeyStore加入一條私鑰並設置與KeyStore相同的密碼
fun main(){
val keyStore = KeyStore.getInstance("PKCS12").apply {
load(File(PATH).inputStream(),PASSWORD.toCharArray())
}
val key = KeyGenerator.getInstance("AES").apply {
init(256,SecureRandom("VARIABLE".toByteArray()))
}.generateKey()
keyStore.setEntry("symmetry",
KeyStore.SecretKeyEntry(key),
KeyStore.PasswordProtection(PASSWORD.toCharArray()))
keyStore.store(File(PATH).outputStream(),PASSWORD.toCharArray())
}
未解鎖前信息都是不可見的
導入祕鑰對
public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain)
#源碼中對證書鏈有說明 數組的0號元素必須和私鑰對應 即0號元素應該是Leaf Certificate
fun main(){
val keyStore = KeyStore.getInstance("PKCS12").apply {
load(File(PATH).inputStream(),PASSWORD.toCharArray())
}
val pair = genKeyPair()
keyStore.setEntry("privateKey",
KeyStore.PrivateKeyEntry(pair.private, certChain),
KeyStore.PasswordProtection(PASSWORD.toCharArray()))
//等效keystore.setKeyEntry("privateKey",pair.private, PASSWORD.toCharArray(),chain)
keyStore.store(File(PATH).outputStream(),PASSWORD.toCharArray())
}
引路
源碼java.security.KeyStore
非對稱加密 https://en.wikipedia.org/wiki/Symmetric-key_algorithm