一尘不染

HSM与Apache Tomcat一起用于HTTPS

tomcat

我的HSM(硬件安全模块)存储(或允许使用)私钥,但是,它不支持PKCS#11和类似方法。反过来,Apache
Tomcat可以通过JKS,PKCS#11或以编程方式使用证书和密钥。我的目标是在Web服务器上启用HTTPS支持,但是我看不到如何仅通过更改配置文件来实现这一点。

我想象一个选项,我可以将证书存储在JKS中,并通过HSM供应商提供的API获得与其关联的私钥。为此,如果我是对的,我将需要重新实现JSSEImplementation和相应的工厂。同样,我将需要实现特定的密钥和信任管理器。

那是解决这种问题的唯一方法吗?

例如,在启动后立即在正在运行的Apache Tomcat独立实例中替换JSSEImplementation是否安全?


阅读 291

收藏
2020-06-16

共1个答案

一尘不染

最后,基于示例,我仅提出以下解决方案。我将<Connector>实例添加到Tomcat配置中,并带有sslImplementationName指向自定义JSSEImplementation类名称的属性,并JSSEImplementation通过自定义JSSESocketFactoryX509KeyManager类进行扩展。

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

CustomJSSEImplementation 类是:

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);
   }
}

CustomSslContextSocketFactory 类是:

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));
    }
}

CustomSslContext 界面是:

interface CustomSslContext {
    KeyManager[] getKeyManagers(JSSESocketFactory factory) throws Exception;
}

HsmKeyManagerImpl通过keyAlias属性在HSM中引用私钥的形式如下:

public class HsmKeyManagerImpl implements X509KeyManager {
    ...

    @Override
    public PrivateKey getPrivateKey(String alias) {
        // HSM Vendor specific API calls
    }
}

我没有显示代码如何获取与私有证书相对应的证书,但是使用的keyAlias属性定义的相同别名<Connector>用于从JKS 获取证书。

2020-06-16