简体   繁体   中英

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. I am needing a KeyStore object to feed to KeyManagerFactory while using init method

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.

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.

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[])

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

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:

// 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.

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). 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"). 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.

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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