我们能否从 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>)
这将只有一个我注入的别名。
那么如何创建这个
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
是相当常见的,在这种情况下
您一起创建密钥对和虚拟证书(包括身份信息)和 密钥库。
但是完全有可能在现有密钥库中创建密钥对和虚拟证书,
在这种情况下,您确实提供了证书身份信息(并且不创建密钥库),
或者在不创建密钥对和虚拟证书的情况下创建密钥库(用作信任库),
在这种情况下,您不提供证书身份信息。
我正在读取 KeyStore 并想提取关于特定别名的详细信息。在使用 init 方法时,我需要一个 KeyStore 对象来提供给 KeyManagerFactory
kmf.init(<OldKeyStoreObject>,<keyStorePwdCharArray>)
但这目前包含多个别名。
我想获取提取的特定别名的私钥和证书,并将其存储到特定变量中。
现在如果我创建一个新的 KeyStore 对象(它是空的),然后注入 私钥和证书存储较早。
当我们使用 KeyTool 创建 keyStore 时,我是否需要提供组织和其他内容的详细信息,如果是,如何在 java 代码中执行相同的操作。
最后我想做的是,
kmf.init(<NewKeyStoreObjectWhichHasInjectedAliasFromOld>,<keyStorePwdCharArray>)
这将只有一个我注入的别名。
那么如何创建这个
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
是相当常见的,在这种情况下
您一起创建密钥对和虚拟证书(包括身份信息)和 密钥库。
但是完全有可能在现有密钥库中创建密钥对和虚拟证书,
在这种情况下,您确实提供了证书身份信息(并且不创建密钥库),
或者在不创建密钥对和虚拟证书的情况下创建密钥库(用作信任库),
在这种情况下,您不提供证书身份信息。