我们能否从 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 并想提取关于特定别名的详细信息。在使用 init 方法时,我需要一个 KeyStore 对象来提供给 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[])

Now what if I create a new KeyStore object(which is empty), Then inject the private key and cert store earlier.

是的,你可以做到。

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 Factory,甚至不需要它创建的标准但隐藏的 [Sun]X509KeyManagerImpl, 但是只有 a X509KeyManager JSSE 可以调用的实例,你可以直接这样做:

// 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"; }
};

Do I need to give the details of Organization and other stuff when we create a keyStore using KeyTool, If yes the how to do the same in java code.

我认为您可能混淆了创建 keypair(或私钥)和创建 keystore

当您使用 keytool 生成(创建)密钥对时,它还会创建一个虚拟自签名 (X.509) 证书, 并且该证书应该识别拥有它的人或实体(以及匹配的私钥)。 该身份以称为 DistinguishedName 的形式表示,它有几个可能的字段(或正式 在 X.500 定义的 ASN.1 中,属性值断言),包括国家、州或省、城市或地方, organization、organizational unit 和 common name(keytool 提示有点误导为 "first and last name")。 该证书中实际需要什么身份信息,例如组织字段是否需要 完全被填满,如果填满,取决于(1)您是否要实际使用虚拟证书, 或用从 CA(证书颁发机构)获得的 'real' 证书替换它,如果是,哪个 CA 使用什么请求程序, (2) 您将使用生成的证书(虚拟或真实)来做什么——HTTPS、其他 SSL/TLS、电子邮件、文档签名 and/or 加密、代码签名等。 -- 简而言之,比您在问题中提供的信息多得多。

在新的密钥库上使用 keytool -genkeypair 是相当常见的,在这种情况下 您一起创建密钥对和虚拟证书(包括身份信息) 密钥库。 但是完全有可能在现有密钥库中创建密钥对和虚拟证书, 在这种情况下,您确实提供了证书身份信息(并且不创建密钥库), 或者在不创建密钥对和虚拟证书的情况下创建密钥库(用作信任库), 在这种情况下,您不提供证书身份信息。