Java HSM与ApacheTomcat的HTTPS使用
我的HSM(硬件安全模块)存储(或允许使用)私钥,但不支持PKCS#11和类似方法。反过来,ApacheTomcat可以通过JKS、PKCS#11或编程方式使用证书和密钥。我的目标是在Web服务器上启用HTTPS支持,但我看不到如何仅通过更改配置文件来实现这一点 我设想一个选项,我可以将证书存储在JKS中,并通过HSM供应商提供的API获取与其关联的私钥。为此,如果我是对的,我将需要重新实施和相应的工厂。此外,我还需要实现特定的密钥和信任管理器 这是解决这个问题的唯一办法吗Java HSM与ApacheTomcat的HTTPS使用,java,tomcat,ssl,hsm,Java,Tomcat,Ssl,Hsm,我的HSM(硬件安全模块)存储(或允许使用)私钥,但不支持PKCS#11和类似方法。反过来,ApacheTomcat可以通过JKS、PKCS#11或编程方式使用证书和密钥。我的目标是在Web服务器上启用HTTPS支持,但我看不到如何仅通过更改配置文件来实现这一点 我设想一个选项,我可以将证书存储在JKS中,并通过HSM供应商提供的API获取与其关联的私钥。为此,如果我是对的,我将需要重新实施和相应的工厂。此外,我还需要实现特定的密钥和信任管理器 这是解决这个问题的唯一办法吗 例如,在Apache
例如,在Apache Tomcat的独立运行实例中替换JSSEImplementation是否安全,就在它启动之后。最后,我仅根据示例提出了以下解决方案。我使用指向自定义
JSSEImplementation
类名的sslImplementationName
属性向Tomcat配置添加
实例,并使用自定义JSSESocketFactory
和X509KeyManager
类扩展JSSEImplementation
Tomcat配置如下所示:
<Connector
protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
clientAuth="true" sslProtocol="TLS" SSLEnabled="true"
sslImplementationName="x.y.z.CustomJSSEImplementation"
keyAlias="alias_of_key_in_HSM_and_cert_in_JKS"
/>
public class HsmKeyManagerImpl implements X509KeyManager {
...
@Override
public PrivateKey getPrivateKey(String alias) {
// HSM Vendor specific API calls
}
}
CustomSslContextSocketFactory
类别为:
public class CustomJSSEImplementation extends JSSEImplementation {
@Override
public ServerSocketFactory getServerSocketFactory(AbstractEndpoint endpoint) {
return new CustomSslContextSocketFactory(endpoint);
}
@Override
public SSLUtil getSSLUtil(AbstractEndpoint endpoint) {
return new CustomSslContextSocketFactory(endpoint);
}
}
public class CustomSslContextSocketFactory extends JSSESocketFactory {
public static final AtomicReference<CustomSslContext> customSslContext =
new AtomicReference<CustomSslContext>();
public CustomSslContextSocketFactory(AbstractEndpoint endpoint) {
super(endpoint);
}
@Override
public KeyManager[] getKeyManagers() throws Exception {
return (customSslContext.get() == null ? super.getKeyManagers() : customSslContext.get().getKeyManagers(this));
}
}
HsmKeyManagerImpl
通过keyalis
属性引用HSM中的私钥,如下所示:
<Connector
protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
clientAuth="true" sslProtocol="TLS" SSLEnabled="true"
sslImplementationName="x.y.z.CustomJSSEImplementation"
keyAlias="alias_of_key_in_HSM_and_cert_in_JKS"
/>
public class HsmKeyManagerImpl implements X509KeyManager {
...
@Override
public PrivateKey getPrivateKey(String alias) {
// HSM Vendor specific API calls
}
}
我没有向代码展示如何获取对应于private的证书,但是使用
的keyalis
属性定义的相同别名从JKS获取证书