Как у меня может быть несколько сертификатов SSL для сервера Java

Хорошо, этот код работал

s = socket.socket()
s.connect((ip,port))
s.send("my request\r")
print s.recv(256)
s.close()

, было довольно трудно работать, которые из Python снабжают документацию модуля сокетом. Таким образом, я приму. Анти-9's ответ.

14
задан Community 23 May 2017 в 11:46
поделиться

2 ответа

Самый простой способ сделать это - использовать один сертификат для всех ваших доменных имен. Поместите все остальные имена сайтов в SAN (альтернативное имя субъекта).

Если вы предпочитаете один сертификат для каждого имени домена, вы можете написать свой собственный менеджер ключей и использовать псевдоним для идентификации домена, чтобы вы могли использовать единое хранилище ключей. В нашей системе мы придерживаемся соглашения, согласно которому псевдоним хранилища ключей всегда равен CN в сертификате. Итак, мы можем сделать что-то вроде этого,

SSLContext sctx1 = SSLContext.getInstance("SSLv3");
sctx1.init(new X509KeyManager[] { 
    new MyKeyManager("/config/master.jks","changeme".toCharArray(),"site1.example.com")
    },null, null);
SSLServerSocketFactory ssf = (SSLServerSocketFactory) sctx1.getServerSocketFactory();
ServerSocket ss1 = ssf.createServerSocket(1234);

...

SSLContext sctx2 = SSLContext.getInstance("SSLv3");
sctx2.init(new X509KeyManager[] { 
    new MyKeyManager("/config/master.jks","changeme".toCharArray(),"site2.example.com") 
    },null, null);
ssf = (SSLServerSocketFactory) sctx2.getServerSocketFactory();
ServerSocket ss2 = ssf.createServerSocket(5678);

...

public static class MyKeyManager implements X509KeyManager {
    private KeyStore keyStore;
    private String alias;
    private char[] password;

    MyKeyManager(String keyStoreFile, char[] password, String alias)
        throws IOException, GeneralSecurityException
    {
        this.alias = alias;
        this.password = password;
        InputStream stream = new FileInputStream(keyStoreFile);
        keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(stream, password);
    }

    public PrivateKey getPrivateKey(String alias) {
        try {
            return (PrivateKey) keyStore.getKey(alias, password);
        } catch (Exception e) {
            return null;
        }
    }

    public X509Certificate[] getCertificateChain(String alias) {
        try {
            java.security.cert.Certificate[] certs = keyStore.getCertificateChain(alias);
            if (certs == null || certs.length == 0)
                return null;
            X509Certificate[] x509 = new X509Certificate[certs.length];
            for (int i = 0; i < certs.length; i++)
                x509[i] = (X509Certificate)certs[i];
            return x509;
        } catch (Exception e) {
            return null;
        }          
    }

    public String chooseServerAlias(String keyType, Principal[] issuers,
                                    Socket socket) {
        return alias;
    }

    public String[] getClientAliases(String parm1, Principal[] parm2) {
        throw new UnsupportedOperationException("Method getClientAliases() not yet implemented.");
    }

    public String chooseClientAlias(String keyTypes[], Principal[] issuers, Socket socket) {
        throw new UnsupportedOperationException("Method chooseClientAlias() not yet implemented.");
    }

    public String[] getServerAliases(String parm1, Principal[] parm2) {
        return new String[] { alias };
    }

    public String chooseServerAlias(String parm1, Principal[] parm2) {
        return alias;
    }
}
8
ответ дан 1 December 2019 в 14:11
поделиться

Вы не сможете использовать SSLServerSocketFactory по умолчанию.

Вместо этого инициализируйте другой SSLContext для каждый сайт, каждый из которых использует KeyManagerFactory , настроенный с хранилищем ключей, содержащим запись ключа с правильным сертификатом сервера. (После инициализации KeyManagerFactory передайте его диспетчеры ключей методу init метода SSLContext .)

После ] SSLContext инициализируется, получает его SSLServerSocketFactory и использует его для создания слушателя.

KeyStore identity = KeyStore.getInstance(KeyStore.getDefaultType());
/* Load the keystore (a different one for each site). */
...
SSLContext ctx = SSLContext.getInstance("TLS");
KeyManagerFactory kmf = 
  KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(identity, password);
ctx.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory factory = ctx.getServerSocketFactory();
ServerSocket server = factory.createSocket(port);
5
ответ дан 1 December 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: