Soru SSL Soket'i etkinleştirmek için hangi Cipher Suites?


İstemci ve sunucu programı arasındaki iletişimi sağlamak için Java'nın SSLSocket kullanıyorum. Sunucu programı ayrıca web tarayıcılarından HTTPS istekleri de sunar.

Göre "Java ile Kriptografiye Başlamak", sayfa 371, her zaman aramalısınız setEnabledCipherSuites senin üstünde SSLSocket / SSLServerSocket Anlaşılan sona eren şifreleme paketinin sizin amaçlarınız için yeterince güçlü olmasını sağlamak.

Bu söyleniyor, benim için bir çağrı SSLSocketFactory'ler getDefaultCipherSuites yöntem bazı verir 180 seçenekler. Bu seçenekler TLS_RSA_WITH_AES_256_CBC_SHA (ki bence oldukça güvenli) SSL_RSA_WITH_RC4_128_MD5 (MD5'in şu anki durumu göz önüne alındığında güvenli ise emin değil) SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (ne yaptığını tam olarak emin değilim).

Soketleri kısıtlamak için şifreli paketlerin makul bir listesi nedir?

İstemcinin ve sunucunun Şişme kale Hizmet sağlayıcısı ve sınırsız kriptografik ilke dosyaları yüklü olabilir veya olmayabilir.


19
2018-06-24 10:41


Menşei


TLS_RSA_WITH_AES_256_CBC_SHA ... - muhtemelen RSA anahtar taşıma şemalarından kaçınmalısınız (veya reklamı yaptığınız listenin en altına yerleştirmelisiniz). Bunun yerine, geçici anahtar değişimlerini tercih edin DHEileri gizlilik için. Aslında TLS 1.3, mülkten yoksun oldukları için kaldırılmalarını tartışıyor. - jww
SSL_RSA_WITH_RC4_128_MD5 ... - RC4 şimdi sorun olan çocuk. Görmek TLS ve WPA’daki RC4’ün Güvenliği Üzerine. Bir saldırgan muhtemelen yapamam forge a HMAC-MD5 Ağın 2MSL zaman penceresinde imza. Bununla birlikte, bir saldırgan, şifreleme akışındaki bitleri istatistiksel olarak ilişkilendirebilir. (Ve MD5 olduğu Sertifikalar ve dijital imzalar gibi uzun süreli kullanım için öldü). - jww
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA ... - yak onu. Veba gibi kaçının. - jww


Cevaplar:


İçinde ihracat ile hiçbir şey kullanmayın. Güçlü kriptografi üzerindeki ihracat kısıtlamaları nedeniyle sakat yazılımlar.

DÜZENLEME: 2009 belgesini kullanmak için değiştirildi.

2009 NIST tavsiye TLS_RSA_WITH_AES_256_CBC_SHA (bahsettiğiniz) dahil olmak üzere aşağıdakileri listeler:

TLS_RSA_WITH_NULL_SHA (Gizlilik / mahremiyete ihtiyacınız olmadığından emin değilseniz bunu kullanmayın).

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 

7
2018-06-24 11:11



TLS_RSA_WITH_NULL_SHA hakkında biraz kafam karışık - bu şifreleme belirtmiyor mu? Bu bağlamda bu demek oluyor yok hayır veya herhangi şifreleme? - Zarkonnen
Zarkonnen, bence doğru TLS_RSA_WITH_NULL_SHA şifreleme yok demektir. s. Bağlantılı taslağın 34'ü NULL şifrelemesinin, "bütünlük korumasının gerekli olduğu ancak şifrelemenin olmadığı durumlarda" olduğunu söylüyor. - Matthew Flaschen
Sanırım Preshared Key (PSK) şifrelerini istiyor gibi. TLS_PSK_WITH_3DES_EDE_CBC_SHA. TLS_RSA_WITH_AES_256_CBC_SHA RSA anahtar taşıma kullanır. Muhtemelen kullanıyor olmalı DHE veya ECDHE ileri gizlilik için. - jww
Şifre paketi özelliklerinin alt bölümlerinin iyi bir açıklaması ve kaçınmanız gerekenler burada: blog.eveoh.nl/2014/02/tls-ssl-ciphers-pfs-tomcat - Søren Boisen


Aşağıda şifre setleri ve protokolleri uygulamak için kullandığım Java sınıfı var. Önce SSLSocketFactoryEx, Üzerinde özellikleri değiştiriyordum SSLSocket Onlara eriştiğimde. Yığın Taşması üzerinde Java millet yardımcı oldu, bu yüzden burada yayınlamak için güzel.

SSLSocketFactoryEx daha güçlü şifre setleri tercih ediyor ECDHE ve DHE) ve zayıf ve yaralı şifre paketlerini (örneğin RC4 ve MD5). TLS 1.2 olduğunda Google ve Microsoft ile birlikte çalışmak için dört adet RSA anahtar taşıma şifresini etkinleştirmek zorundadır. değil mevcut. Onlar TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA ve iki arkadaş. Mümkünse TLS_RSA_* Anahtar taşıma şemaları.

Şifre paketi listesini olabildiğince küçük tutun. Reklamını yaparsan herşey mevcut şifreleri (Flaschen'in listesine benzer), sonra listeniz 80+ olacaktır. Bu 160 bayt kadar sürer ClientHellove bazı aygıtların arızalanmasına neden olabilir, çünkü bunlar işlemek için küçük, sabit boyutlu bir arabelleğe sahiptir. ClientHello. Kırık cihazlar F5 ve Ironport içerir.

Pratikte, tercih edilen liste Java'nın desteklenen şifreleme paketleriyle kesiştiğinde, aşağıdaki koddaki liste 10 veya 15 şifre paketi ile eşleştirilir. Örneğin, bağlamaya hazırlanırken aldığım liste veya microsoft.com veya google.com'u sınırsız bir JCE politikasıyla yürütün:

  • 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

List, RC4 ve MD5 gibi zayıf / yaralanmış algoritmaları atlar. Eğer etkinlerse, muhtemelen bir Tarayıcıdan eski kriptografi uyarısı ara sıra.

İlke, varsayılan JCE ilkesiyle daha küçük olacaktır; çünkü ilke, AES-256'yı ve bazılarını kaldırır. Kısıtlı politika ile 7 şifre suit hakkında düşünüyorum.

SSLSocketFactoryEx sınıf ayrıca TLS 1.0 ve üstü protokollerin kullanılmasını sağlar. Java 8'den önceki Java istemcileri TLS 1.1 ve 1.2'yi devre dışı bırakır. SSLContext.getInstance("TLS") ayrıca gizlice girecek SSLv3 (Java 8'de bile), kaldırmak için adımlar atılmalıdır.

Son olarak, aşağıdaki sınıf TLS 1.3'ün farkındadır, bu yüzden sağlayıcı bunları kullanılabilir hale getirdiğinde çalışmalıdır. *_CHACHA20_POLY1305 Mevcut suitlerin birçoğundan çok daha hızlı oldukları ve daha iyi güvenlik özelliklerine sahip oldukları için şifre takımları tercih edilirse tercih edilir. Google daha önce sunucularına aktardı. Oracle'ın onlara ne zaman sağlayacağından emin değilim. OpenSSL, onlara OpenSSL sağlayacak 1.0.2  1.1.0.

Bunu şöyle kullanabilirsiniz:

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;
}

15
2018-04-29 13:06



Kodu paylaştığınız için teşekkürler. Benim iki meselem var. İlk olarak, anlamadığım şey kodun neden 2 createSockether biri farklı argümanlar ile çalışır? Bunun bir hatası var. Birinin adını değiştirdiysem, in-kod çağrısının aslında hangisi için olduğunu bilmiyorum. İkincisi, bir hata alıyorum List<String> aa = new ArrayList<String>(); `tür listesi genel değildir; argümanlarla parametarize edilemez <String>. - user2192774
Ayrıca, bu kod Bouncy Castle sağlayıcısı kullanıyor mu? Java Crypto kütüphaneleri aşağıdaki gibi algoritmalar içermediğinden: CHACHA20 Kodumdaki Bouncy Castle sunucusunu nerede arayacağımı anlamıyorum. Başka bir konu olarak, "TLS_ECDHE_ECDSA_WITH_CHACHA20_SHA" ve "TLS_ECDHE_RSA_WITH_CHACHA20_SHA" gibi kod şifrelerini görüyorum, bu SHA256 mı? çünkü asıl olarak ihtiyacım olan şey CHACHA256. - user2192774
@ user2192774 - "Neden her biri farklı argümanlara sahip 2 createSocket fonksiyonu içeriyor?" - Aslında 4 veya 5 tanesi var. Çünkü sınıf Java'nın yerini alıyor SSLSocketFactoryOrijinalin yaptığı tüm yöntemleri sağlamak zorundaydı. - jww
@ user2192774 - "Bouncy Castle sağlayıcısını kodumda nereye arayacağımı anlamıyorum ..." - sağlayıcıları değiştirmeli veya başka bir soru sormalısınız. Not: Temel kütüphane (Sun veya Bouncy Castle gibi) algoritmayı sağlamalıdır. SSLSocketFactorEx bunu sağlamaz. - jww
@jww: güzel açıklama, @ user2192774: "Bouncy Castle sağlayıcısını kodumda nereye arayacağımı anlamıyorum ...", İçe aktardım import org.bouncycastle.jce.provider.BouncyCastleProvider; sınıf dosyamda projedeki kavanozla ve özel yapım öncesi sslContext bu satırı dahil Security.addProvider(new BouncyCastleProvider()); hangi gerekli şifreleri almak için bana yardımcı oldu, ama gerekli olmayan şifreleri hariç yukarıdaki yukarıda iyi açıklamalar / örnekler vardır! - srinivas y