14

是否可以在运行时更改密钥库?目前我在执行 server.start() 之前设置 SSL -

sslContextFactory.setTrustStore(ks);
sslContextFactory.setTrustStorePassword(TRUSTSTORE_PASS);
sslContextFactory.setKeyStorePassword(KEYSTORE_PASS); 
ServerConnector https = new ServerConnector(server, sslContextFactory);

server.start()

我想做的是在运行时创建一个证书并使用它。基本上我正在创建一个像 Fiddler 这样的工具,它可以即时创建证书。

4

5 回答 5

6

自 Jetty 9.4.0 以来,此问题已得到修复,请参阅https://github.com/eclipse/jetty.project/issues/918。您现在可以覆盖 Key/TrustStore 等并调用SslContextFactory.reload.

但是请注意,TLS 会话恢复有一个警告:https ://github.com/eclipse/jetty.project/issues/918#issuecomment-250791417 。根据评论,这应该不是普通浏览器的问题,但是谁知道IE,Mobile,非浏览器客户端等。

于 2017-03-26T21:13:11.313 回答
1

在 Jetty 邮件列表中发布这个问题后,我得到的回复是这不是真的可行

于 2013-07-10T22:30:10.100 回答
0

创建您自己的KeyStore实现。

您可以创建一个覆盖KeyStore并将其作为 Jetty 的信任库的类。然后,您可以自由退回任何Certificate您想要的东西。

可能您必须使用 3rd 方库来动态创建证书,因为 Java 无法创建证书(使用官方 API)。您可以为此使用 BouncyCastle。

于 2013-06-11T08:54:00.217 回答
0

我不是 java 安全包方面的专家,但据我所知,没有直接的方法可以从公共 API 创建密钥对。

但是,如果您可以允许您的代码从 sun 的受限包中导入,我是可能的,例如:

import sun.security.x509.*;

这是您正在寻找的代码大纲:

PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
//Validity for next one year
Date to = new Date(from.getTime() + (365) * 86400000l);

CertificateValidity interval = new CertificateValidity(from, to);

BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);

info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));

// Sign the cert
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);

//cert object is ready to use

希望这可以帮助

于 2013-06-08T09:52:22.133 回答
0

这里似乎有两个问题:动态生成证书(“我想做的是在运行时创建一个证书并使用它。 ”)并在不重新启动的情况下设置它(“是否可以在运行时更改密钥库? ”)。

  • 要动态生成证书,您可以使用BouncyCastle 及其X509V3CertificateGenerator

    • 首先,生成一个自签名 CA(带有 CA 基本约束集),例如使用keytool(查看-ext选项了解详细信息)。这将是您的自定义 CA。

    • 从该密钥库中导出证书(仅 CA 证书,而不是其私钥)并将其导入您要使用的客户端。

    • 在您的应用程序中,使用该私钥进行签名X509V3CertificateGenerator,并确保您使用的颁发者 DN 与您在上面生成的 CA 证书的主题 DN 匹配。

    • 然后,您需要使用与您的客户端打算联系的主机名匹配的主题 DN(或主题备用名称)配置证书生成。如果您打算作为某种透明代理自动执行此操作,这可能是一个棘手的问题。(据我所知,当前版本的 Java 无法读取来自 SNI 扩展的名称,至少不能提前或不进行更多手动处理。)更简单的方法当然是将这个主机名作为可配置的工具中的选项。

  • 要在不重新启动服务器的情况下进行设置,您可以实现自己的X509KeyManager保留在SSLContext您正在使用的位置,但您保留参考和自定义访问器以稍后重新配置证书。它当然不一定是“干净”的东西,我还没有尝试过,但原则上它应该可以工作。(您当然应该确保正确处理并发方面。)

    这可能使您不必关闭侦听套接字,重新配置SSLContext并重新启动套接字。考虑到您可能需要与您的应用程序交互(重新配置主机名),这可能是矫枉过正。

于 2013-06-12T14:30:48.960 回答