Вопрос по java, encryption – Какие Cipher Suites включить для SSL Socket?

21

Я использую SSLSocket Java для защиты связи между клиентом и серверной программой. Программа сервера также обслуживает запросы HTTPS от веб-браузеров.

Согласно & quot;Начало криптографии с Java& quot ;, стр. 371, вы всегда должны звонитьsetEnabledCipherSuites на вашеSSLSocket / SSLServerSocket чтобы убедиться, что набор шифров, который в итоге согласовывается, достаточно силен для ваших целей.

Как говорится, звонок в мойSSLSocketFactory& APOS; sgetDefaultCipherSuites метод дает некоторые180 опции. Эти варианты варьируются отTLS_RSA_WITH_AES_256_CBC_SHA (который я считаю довольно безопасным)SSL_RSA_WITH_RC4_128_MD5 (не уверен, что это безопасно, учитывая текущий статус MD5) дляSSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (не совсем уверен, что это делает).

What's a sensible list of cipher suites to restrict the sockets to?

Обратите внимание, что клиент и сервер имеют доступ кНадувной Замок поставщика услуг, и что они могут иметь или не иметь неограниченные файлы криптографической политики.

SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA ... - сожги это. Избегайте этого, как чумы. jww
TLS_RSA_WITH_AES_256_CBC_SHA ... - вам, вероятно, следует избегать схем транспорта ключей RSA (или размещать их внизу вашего рекламируемого списка). Вместо этого отдавайте предпочтение обмену эфемерными ключами, напримерDHEЗа прямую секретность. Фактически, TLS 1.3 обсуждает их удаление, потому что им не хватает свойства. jww
SSL_RSA_WITH_RC4_128_MD5 ... - RC4 это проблема ребенка сейчас. УвидетьOn the Security of RC4 in TLS and WPA, Злоумышленник, вероятно,cannot подделатьHMAC-MD5 подпись во временном окне 2MSL сети. Однако злоумышленник может статистически сопоставлять биты в потоке шифра. (И MD5is мертвые для долгосрочного использования, такие как сертификаты и цифровые подписи). jww

Ваш Ответ

2   ответа
16

который я использую для обеспечения комплектов шифрования и протоколов. ДоSSLSocketFactoryExЯ изменял свойства наSSLSocket когда у меня был доступ к ним. В этом помогали Java-пользователи из Stack Overflow, так что приятно размещать его здесь.

SSLSocketFactoryEx предпочитает более сильные наборы шифров (например,ECDHE а такжеDHE), и он пропускает слабые и раненые наборы шифров (например,RC4 а такжеMD5). Для взаимодействия с Google и Microsoft необходимо включить четыре ключевых шифра RSA для TLS 1.2.not имеется в наличии. Они естьTLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA и двое друзей. Если возможно, вы должны удалитьTLS_RSA_* Ключевые транспортные схемы.

Держите список наборов шифров как можно меньше. Если вы рекламируетеall доступные шифры (аналогично списку Flaschen), тогда ваш список будет более 80+. Это занимает 160 байтов вClientHelloи это может привести к сбою некоторых устройств, поскольку они имеют небольшой буфер фиксированного размера для обработкиClientHello, Сломанные приборы включают F5 и Ironport.

На практике список в приведенном ниже коде соединяется до 10 или 15 наборов шифров, как только предпочтительный список пересекается с поддерживаемыми наборами шифров Java. Например, вот список, который я получаю при подготовке к подключению, или microsoft.com, или google.com с действующей неограниченной политикой JCE:

TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 TLS_DHE_RSA_WITH_AES_128_CBC_SHA TLS_DHE_DSS_WITH_AES_128_CBC_SHA TLS_RSA_WITH_AES_256_CBC_SHA256 TLS_RSA_WITH_AES_256_CBC_SHA TLS_RSA_WITH_AES_128_CBC_SHA256 TLS_RSA_WITH_AES_128_CBC_SHA

В списке отсутствуют слабые / раненые алгоритмы, такие как RC4 и MD5. Если они включены, то вы, скорее всего, получитеУстаревшее криптографическое предупреждение из браузера по случаю.

Список будет меньше с политикой JCE по умолчанию, потому что политика удаляет AES-256 и некоторые другие. Я думаю, что это около 7 комплектов шифров с ограниченной политикой.

SSLSocketFactoryEx Класс также обеспечивает использование протоколов TLS 1.0 и выше. Java-клиенты до Java 8 отключают TLS 1.1 и 1.2.SSLContext.getInstance("TLS") также будет пробиратьсяSSLv3 (даже в Java 8), поэтому необходимо предпринять шаги для его удаления.

Наконец, приведенный ниже класс поддерживает TLS 1.3, поэтому он должен работать, когда поставщик делает их доступными.*_CHACHA20_POLY1305 комплекты шифров предпочтительнее, если они доступны, потому что они намного быстрее, чем некоторые из существующих комплектов, и имеют лучшие свойства безопасности. Google уже развернул его на своих серверах. Я не уверен, когда Oracle предоставит их. OpenSSL предоставит им OpenSSL1.0.2 1.1.0.

Вы можете использовать это так:

URL url = new URL("https://www.google.com:443");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

SSLSocketFactoryEx factory = new SSLSocketFactoryEx();
connection.setSSLSocketFactory(factory);
connection.setRequestProperty("charset", "utf-8");

InputStream input = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(input, "utf-8");
BufferedReader buffer = new BufferedReader(reader);
...
class SSLSocketFactoryEx extends SSLSocketFactory
{
    public SSLSocketFactoryEx() throws NoSuchAlgorithmException, KeyManagementException
    {
        initSSLSocketFactoryEx(null,null,null);
    }

    public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException
    {
        initSSLSocketFactoryEx(km, tm, random);
    }

    public SSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException
    {
        initSSLSocketFactoryEx(ctx);
    }

    public String[] getDefaultCipherSuites()
    {
        return m_ciphers;
    }

    public String[] getSupportedCipherSuites()
    {
        return m_ciphers;
    }

    public String[] getDefaultProtocols()
    {
        return m_protocols;
    }

    public String[] getSupportedProtocols()
    {
        return m_protocols;
    }

    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException
    {
        SSLSocketFactory factory = m_ctx.getSocketFactory();
        SSLSocket ss = (SSLSocket)factory.createSocket(s, host, port, autoClose);

        ss.setEnabledProtocols(m_protocols);
        ss.setEnabledCipherSuites(m_ciphers);

        return ss;
    }

    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
    {
        SSLSocketFactory factory = m_ctx.getSocketFactory();
        SSLSocket ss = (SSLSocket)factory.createSocket(address, port, localAddress, localPort);

        ss.setEnabledProtocols(m_protocols);
        ss.setEnabledCipherSuites(m_ciphers);

        return ss;
    }

    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException
    {
        SSLSocketFactory factory = m_ctx.getSocketFactory();
        SSLSocket ss = (SSLSocket)factory.createSocket(host, port, localHost, localPort);

        ss.setEnabledProtocols(m_protocols);
        ss.setEnabledCipherSuites(m_ciphers);

        return ss;
    }

    public Socket createSocket(InetAddress host, int port) throws IOException
    {
        SSLSocketFactory factory = m_ctx.getSocketFactory();
        SSLSocket ss = (SSLSocket)factory.createSocket(host, port);

        ss.setEnabledProtocols(m_protocols);
        ss.setEnabledCipherSuites(m_ciphers);

        return ss;
    }

    public Socket createSocket(String host, int port) throws IOException
    {
        SSLSocketFactory factory = m_ctx.getSocketFactory();
        SSLSocket ss = (SSLSocket)factory.createSocket(host, port);

        ss.setEnabledProtocols(m_protocols);
        ss.setEnabledCipherSuites(m_ciphers);

        return ss;
    }

    private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)
    throws NoSuchAlgorithmException, KeyManagementException
    {
        m_ctx = SSLContext.getInstance("TLS");
        m_ctx.init(km, tm, random);

        m_protocols = GetProtocolList();
        m_ciphers = GetCipherList();
    }

    private void initSSLSocketFactoryEx(SSLContext ctx)
    throws NoSuchAlgorithmException, KeyManagementException
    {
        m_ctx = ctx;

        m_protocols = GetProtocolList();
        m_ciphers = GetCipherList();
    }

    protected String[] GetProtocolList()
    {
        String[] preferredProtocols = { "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" };
        String[] availableProtocols = null;

        SSLSocket socket = null;

        try
        {
            SSLSocketFactory factory = m_ctx.getSocketFactory();
            socket = (SSLSocket)factory.createSocket();

            availableProtocols = socket.getSupportedProtocols();
            Arrays.sort(availableProtocols);
        }
        catch(Exception e)
        {
            return new String[]{ "TLSv1" };
        }
        finally
        {
            if(socket != null)
                socket.close();
        }

        List<String> aa = new ArrayList<String>();
        for(int i = 0; i < preferredProtocols.length; i++)
        {
            int idx = Arrays.binarySearch(availableProtocols, preferredProtocols[i]);
            if(idx >= 0)
                aa.add(preferredProtocols[i]);
        }

        return aa.toArray(new String[0]);
    }

    protected String[] GetCipherList()
    {
        String[] preferredCiphers = {

            // *_CHACHA20_POLY1305 are 3x to 4x faster than existing cipher suites.
            //   http://googleonlinesecurity.blogspot.com/2014/04/speeding-up-and-strengthening-https.html
            // Use them if available. Normative names can be found at (TLS spec depends on IPSec spec):
            //   http://tools.ietf.org/html/draft-nir-ipsecme-chacha20-poly1305-01
            //   http://tools.ietf.org/html/draft-mavrogiannopoulos-chacha-tls-02
            "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
            "TLS_ECDHE_ECDSA_WITH_CHACHA20_SHA",
            "TLS_ECDHE_RSA_WITH_CHACHA20_SHA",

            "TLS_DHE_RSA_WITH_CHACHA20_POLY1305",
            "TLS_RSA_WITH_CHACHA20_POLY1305",
            "TLS_DHE_RSA_WITH_CHACHA20_SHA",
            "TLS_RSA_WITH_CHACHA20_SHA",

            // Done with bleeding edge, back to TLS v1.2 and below
            "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
            "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",

            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
            "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
            "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",

            // TLS v1.0 (with some SSLv3 interop)
            "TLS_DHE_RSA_WITH_AES_256_CBC_SHA384",
            "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
            "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
            "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",

            "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
            "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
            "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA",
            "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA",

            // RSA key transport sucks, but they are needed as a fallback.
            // For example, microsoft.com fails under all versions of TLS
            // if they are not included. If only TLS 1.0 is available at
            // the client, then google.com will fail too. TLS v1.3 is
            // trying to deprecate them, so it will be interesteng to see
            // what happens.
            "TLS_RSA_WITH_AES_256_CBC_SHA256",
            "TLS_RSA_WITH_AES_256_CBC_SHA",
            "TLS_RSA_WITH_AES_128_CBC_SHA256",
            "TLS_RSA_WITH_AES_128_CBC_SHA"
        };

        String[] availableCiphers = null;

        try
        {
            SSLSocketFactory factory = m_ctx.getSocketFactory();
            availableCiphers = factory.getSupportedCipherSuites();
            Arrays.sort(availableCiphers);
        }
        catch(Exception e)
        {
            return new String[] {
                "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
                "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
                "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
                "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
                "TLS_RSA_WITH_AES_256_CBC_SHA256",
                "TLS_RSA_WITH_AES_256_CBC_SHA",
                "TLS_RSA_WITH_AES_128_CBC_SHA256",
                "TLS_RSA_WITH_AES_128_CBC_SHA",
                "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"
            };
        }

        List<String> aa = new ArrayList<String>();
        for(int i = 0; i < preferredCiphers.length; i++)
        {
            int idx = Arrays.binarySearch(availableCiphers, preferredCiphers[i]);
            if(idx >= 0)
                aa.add(preferredCiphers[i]);
        }

        aa.add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV");

        return aa.toArray(new String[0]);
    }

    private SSLContext m_ctx;

    private String[] m_ciphers;
    private String[] m_protocols;
}
Error: User Rate Limit ExceededcreateSocketError: User Rate Limit ExceededList<String> aa = new ArrayList<String>();Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededCHACHA20Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded" I do not see where I should call the Bouncy Castle provider in my code..."Error: User Rate Limit Exceededimport org.bouncycastle.jce.provider.BouncyCastleProviderError: User Rate Limit ExceededsslContextError: User Rate Limit ExceededSecurity.addProvider(new BouncyCastleProvider());Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded" I do not see where I should call the Bouncy Castle provider in my code..."Error: User Rate Limit ExceededSSLSocketFactorExError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded"why the code contains 2 createSocket functions each with different arguments?"Error: User Rate Limit ExceededSSLSocketFactoryError: User Rate Limit Exceeded
7

печением из-за ограничений на экспорт сильной криптографии.

РЕДАКТИРОВАТЬ: Изменено для использования документа 2009 года.

2009 NISTрекомендация перечисляет следующее, включая TLS_RSA_WITH_AES_256_CBC_SHA (о котором вы упомянули):

TLS_RSA_WITH_NULL_SHA (не используйте это, если вы не уверены, что вам не нужна конфиденциальность / конфиденциальность).

TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DH_DSS_WITH_AES_128_CBC_SHA
TLS_DH_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DH_DSS_WITH_AES_256_CBC_SHA
TLS_DH_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_PSK_WITH_3DES_EDE_CBC_SHA
TLS_PSK_WITH_AES_128_CBC_SHA
TLS_PSK_WITH_AES_256_CBC_SHA
TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
TLS_DHE_PSK_WITH_AES_128_CBC_SHA
TLS_DHE_PSK_WITH_AES_256_CBC_SHA
TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
TLS_RSA_PSK_WITH_AES_128_CBC_SHA
TLS_RSA_PSK_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededblog.eveoh.nl/2014/02/tls-ssl-ciphers-pfs-tomcat
Error: User Rate Limit ExceededTLS_PSK_WITH_3DES_EDE_CBC_SHA. TLS_RSA_WITH_AES_256_CBC_SHAError: User Rate Limit ExceededDHEError: User Rate Limit ExceededECDHEError: User Rate Limit Exceeded
Error: User Rate Limit ExceedednoError: User Rate Limit ExceededanyError: User Rate Limit Exceeded Zarkonnen

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