繁体   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