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

I am reading a KeyStore and want to extract the details with respect to specific alias.我正在阅读 KeyStore 并想提取有关特定别名的详细信息。 I am needing a KeyStore object to feed to KeyManagerFactory while using init method我需要一个 KeyStore 对象在使用 init 方法时提供给 KeyManagerFactory

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

But this for now contains multiple alias.但这暂时包含多个别名。

I want to get the Private key and cert of specific the alias extracted and store it into specific variables.我想获取提取的特定别名的私钥和证书,并将其存储到特定变量中。

Now what if I create a new KeyStore object(which is empty), Then inject the private key and cert store earlier.现在,如果我创建一个新的 KeyStore 对象(它是空的),然后更早地注入私钥和证书存储会怎样。

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.当我们使用 KeyTool 创建 keyStore 时,我是否需要提供组织和其他内容的详细信息,如果是,在 java 代码中如何做同样的事情。

Finally I want to do is,最后我想做的是,

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

Which will be having only one alias which i injected.这将只有一个我注入的别名。

So how to create this那么如何创建这个

Refer this https://docs.oracle.com/javase/7/docs/api/java/security/KeyStore.html#setKeyEntry(java.lang.String,%20java.security.Key,%20char[],%20java.security.cert.Certificate[])请参阅此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 对象(它是空的),然后更早地注入私钥和证书存储会怎样。

Yes, you can do this.是的,你可以这样做。

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

Alternatively, if you are really creating an SSLContext, you don't really need a KeyManager Factory or even the standard but hidden [Sun]X509KeyManagerImpl it creates, but only a X509KeyManager instance that JSSE can call, you can do that directly:或者,如果您真的要创建 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"; }
};

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.当我们使用 KeyTool 创建 keyStore 时,我是否需要提供组织和其他内容的详细信息,如果是,在 java 代码中如何做同样的事情。

I think you may be confusing creating a keypair (or privatekey) and creating a keystore .我认为您可能会混淆创建密钥对(或私钥)和创建密钥库

When you use keytool to generate (create) a keypair, it also creates a dummy selfsigned (X.509) certificate, and that certificate is supposed to identify the person or entity owning it (and the matching privatekey).当您使用 keytool 生成(创建)密钥对时,它还会创建一个虚拟的自签名 (X.509) 证书,并且该证书应该标识拥有它的个人或实体(以及匹配的私钥)。 That identity is represented in a form called DistinguishedName, which has several possible fields (or formally in the ASN.1 defined by X.500, Attribute Value Assertions), including country, state or province, city or locality, organization, organizational unit, and common name (which keytool prompts somewhat misleadingly as "first and last name").该身份以称为 DistinguishedName 的形式表示,它有几个可能的字段(或正式在 X.500 定义的 ASN.1,属性值断言中),包括国家、州或省、城市或地区、组织、组织单位、和通用名称(keytool 提示有点误导为“名字和姓氏”)。 What identity info is actually needed in this cert, for example whether the organization field needs to be filled at all and if so with what, depends on (1) whether you are going to actually use the dummy cert, or replace it with a 'real' cert obtained from a CA (Certificate Authority), and if so which CA using what request procedure, and (2) what you will use the resulting cert (either dummy or real) for -- HTTPS, other SSL/TLS, email, document signing and/or encryption, code signing, etc. -- in short, a lot more info than you provided in your question.此证书中实际需要哪些身份信息,例如是否需要填写组织字段,如果需要填写什么,取决于 (1) 您是否要实际使用虚拟证书,或将其替换为 '从 CA(证书颁发机构)获得的真实'证书,如果是这样,哪个 CA 使用什么请求程序,以及 (2) 您将使用生成的证书(虚拟或真实)用于 - HTTPS、其他 SSL/TLS、电子邮件、文档签名和/或加密、代码签名等——简而言之,比您在问题中提供的信息多得多。

It is fairly common to use keytool -genkeypair on a new keystore, in which case you create the keypair and dummy cert (including identity info) and keystore together.在新密钥库上使用keytool -genkeypair是相当常见的,在这种情况下,您可以一起创建密钥对和虚拟证书(包括身份信息)密钥库。 But it is entirely possible to create a keypair and dummy cert in an existing keystore, in which case you do supply the certificate identity info (and don't create the keystore), or to create a keystore (for use as truststore) without creating a keypair and dummy cert, in which case you don't supply certificate identity info.但是完全有可能在现有密钥库中创建密钥对和虚拟证书,在这种情况下,您确实提供证书身份信息(并且不创建密钥库),或者创建密钥库(用作信任库)而不创建密钥对和虚拟证书,在这种情况下,您不提供证书身份信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM