Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我们是否可以从java.security.KeyStore对象及其密钥对和证书中提取特定别名,然后注入新的java.security.KeyStore对象?_Java_Ssl_Keystore - Fatal编程技术网

我们是否可以从java.security.KeyStore对象及其密钥对和证书中提取特定别名,然后注入新的java.security.KeyStore对象?

我们是否可以从java.security.KeyStore对象及其密钥对和证书中提取特定别名,然后注入新的java.security.KeyStore对象?,java,ssl,keystore,Java,Ssl,Keystore,我正在阅读一个密钥库,希望提取有关特定别名的详细信息。在使用init方法时,我需要一个KeyStore对象提供给KeyManagerFactory kmf.init(<OldKeyStoreObject>,<keyStorePwdCharArray>) kmf.init(,) 但现在这个包含多个别名 我想获取提取的特定别名的私钥和证书,并将其存储到特定变量中 现在,如果我创建一个新的密钥库对象(它是空的),然后注入 私钥和证书存储较早 当我们使用KeyTool创建密

我正在阅读一个密钥库,希望提取有关特定别名的详细信息。在使用init方法时,我需要一个KeyStore对象提供给KeyManagerFactory

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

kmf.init(,)
但现在这个包含多个别名

我想获取提取的特定别名的私钥和证书,并将其存储到特定变量中

现在,如果我创建一个新的密钥库对象(它是空的),然后注入 私钥和证书存储较早

当我们使用KeyTool创建密钥库时,我是否需要提供组织和其他方面的详细信息,如果需要,如何在java代码中进行同样的操作

最后我想做的是

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

kmf.init(,)
只有我注入的一个别名

那么如何创建这个呢

参考此

现在,如果我创建一个新的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创建密钥库时,我是否需要提供组织和其他方面的详细信息,如果需要,如何在java代码中进行同样的操作

我认为您可能会混淆创建密钥对(或私钥)和创建密钥库

当您使用keytool生成(创建)密钥对时,它还会创建一个伪自签名(X.509)证书, 该证书应该能够识别拥有它的个人或实体(以及匹配的私钥)。 该标识以一种称为DifferentizedName的形式表示,它有几个可能的字段(或形式上的字段) 在X.500定义的ASN.1中,属性值断言),包括国家、州或省、市或地方, 组织、组织单位和通用名称(keytool提示的“名字和姓氏”有点误导性)。 此证书中实际需要哪些身份信息,例如组织字段是否需要 是否填写,如果填写内容,取决于(1)您是否实际使用虚拟证书, 或者将其替换为从CA(证书颁发机构)获得的“真实”证书,如果是,哪个CA使用什么请求程序, (2)您将使用生成的证书(虚拟证书或真实证书)进行哪些操作--HTTPS、其他SSL/TLS、电子邮件、文档签名和/或加密、代码签名等。 --简而言之,比你在问题中提供的信息要多得多

在新的密钥库上使用
keytool-genkeypair
是很常见的,在这种情况下 您可以一起创建密钥对、虚拟证书(包括身份信息)和密钥库。 但完全可以在现有密钥库中创建密钥对和虚拟证书, 在这种情况下,您提供证书标识信息(而不创建密钥库), 或者在不创建密钥对和虚拟证书的情况下创建密钥库(用作信任库),
在这种情况下,您不提供证书身份信息。

为什么像chooseClientAlias chooseServerAlias,我的意思是为什么客户端和服务器而不仅仅是chooseAlias?当我们使用KeyTool创建密钥库时,我们没有指定这样的内容,对吗?为什么别名、客户端或服务器依赖于此?另外,在X509ExtendedKeyManager中的每个方法之前,我们是否需要有
@Override
?(1)选择{}别名是KeyManager的一个函数,在握手过程中,keytool不参与其中。keytool确实允许您指定新条目的别名(或更改现有条目),并且该别名(或这些名称)是KeyManager通常“选择”并告诉JSSE使用的名称。对于TLS(2),您不需要
@覆盖
;Java最初是在没有它的情况下定义的,而且它是可选的,尽管如果您犯了错误,它会给您一个快速、具体的诊断,而不是以您意想不到的方式“神秘地”分派。您的选择。我也得到了
java.lang.ClassCastException:[Ljava.security.cert.Certificate;无法转换为[Ljava.security.cert.X509Certificate
。我猜转换不起作用。