簡體   English   中英

我們可以從帶有密鑰對和證書的 java.security.KeyStore 對象中提取一個特定的別名,然后注入到一個新的 java.security.KeyStore 對象中嗎?

[英]Can we extract a specific alias from a java.security.KeyStore object with its keypair and cert, then inject into a new java.security.KeyStore object?

我正在閱讀 KeyStore 並想提取有關特定別名的詳細信息。 我需要一個 KeyStore 對象在使用 init 方法時提供給 KeyManagerFactory

kmf.init(<OldKeyStoreObject>,<keyStorePwdCharArray>)

但這暫時包含多個別名。

我想獲取提取的特定別名的私鑰和證書,並將其存儲到特定變量中。

現在,如果我創建一個新的 KeyStore 對象(它是空的),然后更早地注入私鑰和證書存儲會怎樣。

當我們使用 KeyTool 創建 keyStore 時,我是否需要提供組織和其他內容的詳細信息,如果是,在 java 代碼中如何做同樣的事情。

最后我想做的是,

kmf.init(<NewKeyStoreObjectWhichHasInjectedAliasFromOld>,<keyStorePwdCharArray>)

這將只有一個我注入的別名。

那么如何創建這個

請參閱此https://docs.oracle.com/javase/7/docs/api/java/security/KeyStore.html#setKeyEntry(java.lang.String,%20java.security.Key,%20char[],%20java .security.cert.Certificate[])

現在,如果我創建一個新的 KeyStore 對象(它是空的),然后更早地注入私鑰和證書存儲會怎樣。

是的,你可以這樣做。

KeyStore one = KeyStore.getInstance(your_ks_type); // optionally add ,provider
try(InputStream is = new FileInputStream(filename)){ one.load(is,pw); }
// or other input source like JAR, server, whatever
PrivateKey privkey = (PrivateKey) one.getKey (alias,pw);
// keypass is _usually_ same as storepass but may differ for some keystores like JKS 
Certificate[] chain one.getCertificateChain (alias);
// use java.security.cert.Certificate, not the obsolete java.security.Certificate 

KeyStore two = KeyStore.getInstance("JKS"); // any filebased type (and optionally provider)
// doesn't matter which since we don't read or write it
two.load(null); // dummy call makes it ready to use
two.setKeyEntry (dummyalias, privkey, pwx, chain);
// two now contains (in memory only) the single privateKey entry

或者,如果您真的要創建 SSLContext,則您實際上不需要 KeyManager工廠,甚至不需要它創建的標准但隱藏的 [Sun]X509KeyManagerImpl,而只需要JSSE 可以調用X509KeyManager 實例,您可以直接執行此操作:

// get privkey and chain from keystore to local variables as above
// below Java 8 must declare them final (after that it's implicit) 
one = null; // so _not_ effectively captured

KeyManager km = new X509ExtendedKeyManager (){
  // anonymous (local) class captures privkey and chain variables from containing method
  public X509Certificate[] getCertificateChain(String alias){ return (X509Certificate[]) chain; }
  // KeyStore API is declared using abstract java.security.cert.Certificate but implementations 
  // actually use specific java.security.cert.X509Certificate or a subclass so cast works
  public PrivateKey getPrivateKey(String alias){ return privkey; }
  public String[] getClientAliases(String keyType, Principal[] issuers){ return new String[]{"dummy"}; }
  public String[] getServerAliases(String keyType, Principal[] issuers){ return new String[]{"dummy"}; }
  // at least one of these depending how this (context and) keymanager will be used:
  public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket){ return "dummy"; }
  public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket){ return "dummy"; }
  public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine){ return "dummy"; }
  public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine){ return "dummy"; }
};

當我們使用 KeyTool 創建 keyStore 時,我是否需要提供組織和其他內容的詳細信息,如果是,在 java 代碼中如何做同樣的事情。

我認為您可能會混淆創建密鑰對(或私鑰)和創建密鑰庫

當您使用 keytool 生成(創建)密鑰對時,它還會創建一個虛擬的自簽名 (X.509) 證書,並且該證書應該標識擁有它的個人或實體(以及匹配的私鑰)。 該身份以稱為 DistinguishedName 的形式表示,它有幾個可能的字段(或正式在 X.500 定義的 ASN.1,屬性值斷言中),包括國家、州或省、城市或地區、組織、組織單位、和通用名稱(keytool 提示有點誤導為“名字和姓氏”)。 此證書中實際需要哪些身份信息,例如是否需要填寫組織字段,如果需要填寫什么,取決於 (1) 您是否要實際使用虛擬證書,或將其替換為 '從 CA(證書頒發機構)獲得的真實'證書,如果是這樣,哪個 CA 使用什么請求程序,以及 (2) 您將使用生成的證書(虛擬或真實)用於 - HTTPS、其他 SSL/TLS、電子郵件、文檔簽名和/或加密、代碼簽名等——簡而言之,比您在問題中提供的信息多得多。

在新密鑰庫上使用keytool -genkeypair是相當常見的,在這種情況下,您可以一起創建密鑰對和虛擬證書(包括身份信息)密鑰庫。 但是完全有可能在現有密鑰庫中創建密鑰對和虛擬證書,在這種情況下,您確實提供證書身份信息(並且不創建密鑰庫),或者創建密鑰庫(用作信任庫)而不創建密鑰對和虛擬證書,在這種情況下,您不提供證書身份信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM