2016-11-15 5 views
1

Mein HSM (Hardwaresicherheitsmodul) speichert (oder ermöglicht die Verwendung) eines privaten Schlüssels, unterstützt jedoch PKCS # 11 und ähnliche Methoden nicht. Im Gegenzug kann Apache Tomcat mit Zertifikaten und Schlüsseln entweder über JKS, PKCS # 11 oder programmatisch arbeiten. Mein Ziel ist es, die HTTPS-Unterstützung auf einem Webserver zu aktivieren, aber ich sehe keine Möglichkeit, dies nur mit Änderungen in den Konfigurationsdateien zu erreichen.HSM-Verwendung mit Apache Tomcat für HTTPS

Ich stelle mir eine Option vor, dass ich ein Zertifikat in JKS speichern und einen privaten Schlüssel über die von HSM zur Verfügung gestellte API erhalten könnte. Zu diesem Zweck muss ich, wenn ich recht habe, JSSEImplementation und die entsprechenden Fabriken neu implementieren. Außerdem muss ich spezifische Key- und Trust-Manager implementieren.

Ist das der einzige Weg, um ein solches Problem zu lösen?

Ist es beispielsweise sicher, JSSEImplementation in einer laufenden eigenständigen Instanz von Apache Tomcat zu ersetzen, nachdem sie gestartet wurde?

Antwort

1

Schließlich kam ich nur auf die Lösung unten basierend auf this Beispiel. Ich füge <Connector> Instanz der Tomcat-Konfiguration mit sslImplementationName -Eigenschaft hinzu, die auf den benutzerdefinierten Klassennamen JSSEImplementation verweist, und Erweitere JSSEImplementation mit benutzerdefinierten JSSESocketFactory und Klassen.

Tomcat-Konfiguration wie folgt aussieht:

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

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

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 Schnittstelle ist:

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

HsmKeyManagerImpl, die von einer keyAlias Eigenschaft im HSM privaten Schlüsseln Referenz wie folgt aussieht:

public class HsmKeyManagerImpl implements X509KeyManager { 
    ... 

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

ich den Code nicht zeigte, wie Zertifikat zu erhalten, die an den privaten entspricht, aber das gleiche Alias ​​definiert durch Die keyAlias Eigenschaft der <Connector> wird verwendet, um es von der JKS zu bekommen.