HSM usage with Apache Tomcat for HTTPS

你。 提交于 2019-12-05 09:03:16

问题


My HSM (Hardware Security Module) stores (or allows to use) private key, however, it does not support PKCS#11 and similar method. In turn, Apache Tomcat might work with certificate and keys either via JKS, PKCS#11 or programmatically. My goal is to enable HTTPS support on a Web server, but I see no way how to achieve that with changes in configuration files only.

I imagine an option that I could store certificate in JKS, and get private key associated with it via HSM vendor provided API. For that purpose, if I am right, I will need to re-implement JSSEImplementation and corresponding factories. As well, I will need to implement specific Key and Trust Managers.

Is that the only way to solve such problem?

Is it safe to replace JSSEImplementation in a running standalone instance of Apache Tomcat, for instance, right after it started.


回答1:


Finally, I came up only to the solution below based on this example. I add <Connector> instance to the Tomcat configuration with sslImplementationName property pointing to the custom JSSEImplementation class name, and extend JSSEImplementation with custom JSSESocketFactory and X509KeyManager classes.

Tomcat configuration looks like:

<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 class is:

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 class is:

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 is:

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

HsmKeyManagerImpl which reference private key in the HSM by an keyAlias property looks like:

public class HsmKeyManagerImpl implements X509KeyManager {
    ...

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

I didn't show the code how to obtain certificate which corresponds to the private, but the same alias defined by the keyAlias property of the <Connector> is used to get it from the JKS.



来源:https://stackoverflow.com/questions/40620939/hsm-usage-with-apache-tomcat-for-https

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!