首页 文章

Java DefaultSslContextFactory密钥库动态更新

提问于
浏览
3

我有一个使用 org.restlet.engine.ssl.DefaultSslContextFactory 的现有应用程序和一个在服务器启动时加载的密钥库文件 . 我有另一个应用程序创建证书,必须在服务器运行时动态添加到密钥库文件 . 为了执行此操作,我在代码中创建了证书和私钥,然后将其写入目录 . 该目录由检查新文件的bash脚本监视,如果出现,则将其导入现有密钥库文件 .

但是,当尝试使用新导入的证书访问服务器时,握手失败 . 只有在重新启动服务器时,才能成功完成访问,我认为这意味着服务器不会重新加载添加的证书 .

有没有办法用密钥库文件中的新条目更新正在运行的应用程序?

3 回答

  • 0

    将新证书导入密钥库不会刷新当前的SSLConext,因为没有告诉JVM密钥库已更改 .

    要做到这一点,你有可能 - 顺便说一句,你可以将新证书添加到当前的SSLContext See here中 .

    要实现这一点,您需要提供一个知道新证书的bean - 可以是调用您的bash脚本的组件 - 您注入了SSLContext实例 .

    如果您使用微服务架构拆分应用程序,将一个模块委托给一个模块来处理证书并重新加载它(使用适当的配置LB)随着密钥库的更新,这也很有趣 .

  • 0

    由于这似乎是一项非常不可能完成的任务,我决定采取一种解决方法 . 我在应用程序前面使用nginx作为代理 . Nginx能够使用多个CA根证书执行客户端身份验证,这正是我所需要的 . 应用程序和nginx之间的连接可以简单地通过HTTP完成,因为它们驻留在同一主机(只是不同的端口)上 .

  • 0

    Ugly Hack Alert

    以下适用于我 . 我覆盖DefaultSSLContextFactory,存储每个创建的SSLContext并再次调用它的init方法 .

    要调用重新加载,我只需调用UglyHackSSLContextFactory.reloadKeyStore()

    package test;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.security.KeyManagementException;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.SecureRandom;
    import java.security.UnrecoverableKeyException;
    import java.security.cert.CertificateException;
    import java.util.ArrayList;
    
    import javax.net.ssl.SSLContext;
    
    import org.restlet.engine.ssl.DefaultSslContextFactory;
    
    public class UglyHackSSLContextFactory extends DefaultSslContextFactory {
    
        private SSLContext _context = null;
        public static ArrayList<UglyHackSSLContextFactory> instances = new ArrayList<UglyHackSSLContextFactory>();
    
        // we need all used SSLContextFactories later, so store them
        public UglyHackSSLContextFactory() {
            instances.add(this);
        }
    
        // create a new context once and store it.
        @Override
        public SSLContext createSslContext() throws Exception {
            if (this._context == null) {
                this._context = super.createSslContext();
            }
            return this._context;
        }
    
        // re-init all _context instances
        public static void reload() throws KeyManagementException, UnrecoverableKeyException,
                KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException,
                CertificateException, IOException {
            for (final UglyHackSSLContextFactory f : instances) {
                f.reinit();
            }
        }
    
        // this is mostly copied from
        // org.restlet.engine.ssl.DefaultSslContextFactory
        private void reinit() throws KeyManagementException, KeyStoreException,
                NoSuchProviderException, NoSuchAlgorithmException, CertificateException, IOException,
                UnrecoverableKeyException {
    
            javax.net.ssl.KeyManagerFactory kmf = null;
    
            if ((getKeyStorePath() != null) || (getKeyStoreProvider() != null)
                    || (getKeyStoreType() != null)) {
                // Loads the key store.
                final KeyStore keyStore = (getKeyStoreProvider() != null) ? KeyStore.getInstance(
                        (getKeyStoreType() != null) ? getKeyStoreType() : KeyStore.getDefaultType(),
                        getKeyStoreProvider()) : KeyStore
                        .getInstance((getKeyStoreType() != null) ? getKeyStoreType() : KeyStore
                                .getDefaultType());
                FileInputStream keyStoreInputStream = null;
    
                try {
                    keyStoreInputStream = ((getKeyStorePath() != null) && (!"NONE"
                            .equals(getKeyStorePath()))) ? new FileInputStream(getKeyStorePath())
                            : null;
                    keyStore.load(keyStoreInputStream, getKeyStorePassword());
                } finally {
                    if (keyStoreInputStream != null) {
                        keyStoreInputStream.close();
                    }
                }
    
                // Creates the key-manager factory.
                kmf = javax.net.ssl.KeyManagerFactory.getInstance(getKeyManagerAlgorithm());
                kmf.init(keyStore, getKeyStoreKeyPassword());
            }
    
            javax.net.ssl.TrustManagerFactory tmf = null;
    
            if ((getTrustStorePath() != null) || (getTrustStoreProvider() != null)
                    || (getTrustStoreType() != null)) {
                // Loads the trust store.
                final KeyStore trustStore = (getTrustStoreProvider() != null) ? KeyStore
                        .getInstance(
                                (getTrustStoreType() != null) ? getTrustStoreType() : KeyStore
                                        .getDefaultType(), getTrustStoreProvider()) : KeyStore
                        .getInstance((getTrustStoreType() != null) ? getTrustStoreType() : KeyStore
                                .getDefaultType());
                FileInputStream trustStoreInputStream = null;
    
                try {
                    trustStoreInputStream = ((getTrustStorePath() != null) && (!"NONE"
                            .equals(getTrustStorePath()))) ? new FileInputStream(getTrustStorePath())
                            : null;
                    trustStore.load(trustStoreInputStream, getTrustStorePassword());
                } finally {
                    if (trustStoreInputStream != null) {
                        trustStoreInputStream.close();
                    }
                }
    
                // Creates the trust-manager factory.
                tmf = javax.net.ssl.TrustManagerFactory.getInstance(getTrustManagerAlgorithm());
                tmf.init(trustStore);
            }
    
            SecureRandom sr = null;
    
            if (getSecureRandomAlgorithm() != null) {
                sr = SecureRandom.getInstance(getSecureRandomAlgorithm());
            }
    
            this._context.init(kmf != null ? kmf.getKeyManagers() : null,
                    tmf != null ? tmf.getTrustManagers() : null, sr);
    
        }
    
    }
    

    希望这可以帮助!

相关问题