SSLSocket и AES-шифрование - PullRequest
       23

SSLSocket и AES-шифрование

0 голосов
/ 27 января 2012

Нам нужно использовать шифрование AES для связи клиент-сервер, поэтому, когда я включаю Cipher Suite TLS_DHE_RSA_WITH_AES_128_CBC_SHA на SSLServetSocket (используя Java 6) и запускаю программу, я получаю исключение ниже

НетДоступный сертификат или ключ соответствуют комплектам шифров SSL, которые включены

Мой вопрос: можем ли мы шифровать AES через SSLSocket или это должен быть обычный сокет?Если мы не можем использовать его, кто-нибудь может предоставить мне пример взаимодействия клиент-сервер с использованием шифрования AES.

Вот код

public class AESServerSocketTest {

    public static void main(String[] args) {
        SSLServerSocket serverSocket;
        try 
        {
            SSLContext ctx = javax.net.ssl.SSLContext.getDefault();
            serverSocket =(SSLServerSocket)ctx.getServerSocketFactory().createServerSocket(8181);
            serverSocket.setEnabledCipherSuites(new String[]{"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"});        

            SSLSocket in = (SSLSocket)serverSocket.accept(); 
        }
        catch (Exception e) 
        {
            System.out.println("Exception " + e);
        }
    }
}

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 27 января 2012

Анонимные комплекты шифров не выполняют никакой аутентификации.Даже с шифрованием вы говорите по зашифрованному каналу с удаленной стороной, но вы не можете быть уверены, кто это, так что это может быть человек посередине (MITM).В спецификации TLS 1.1 говорится об анонимных комплектах шифров:

Следующие комплекты шифров используются для полностью анонимных соединений Диффи-Хеллмана, в которых ни одна из сторон не аутентифицирована.Обратите внимание, что этот режим уязвим для атак «человек посередине» и поэтому устарел.

Короче, не используйте их (за исключением тестирования), или, если вы действительноуверен, что не будет активного MITM.(Спецификация TLS 1.2 еще более строго сформулирована против их использования.)

Если вы хотите использовать TLS безопасно, вам понадобится способ для клиента проверить удаленную сторону удостоверения.В подавляющем большинстве случаев это делается с использованием сертификата X.509.В частности, для набора шифров TLS_DHE_RSA_WITH_AES_128_CBC_SHA вам потребуется сертификат с открытым ключом RSA (который объясняет полученное вами сообщение об ошибке).

Вы должны сгенерировать или запросить сертификат (самоподписанныйили через центр сертификации, возможно, собственный, в зависимости от того, как клиенты могут быть настроены), который правильно идентифицирует сервер.Клиенту нужно доверять не только сертификату (либо явно, либо через установленный ЦС), но и его идентификационные данные должны совпадать с данными сервера под именем, к которому клиент пытается подключиться.

Из вашего примера не ясно, используете ли вы HTTPS (например) или свой собственный протокол по SSL / TLS. RFC 6125 - это новейшая спецификация в этой области, которая объединяет методы работы с несколькими протоколами (например, HTTPS, LDAPS, IMAPS, ...).Поскольку это довольно недавний RFC, лишь немногие библиотеки явно его реализуют (хотя на практике это возможно, поскольку он объединяет лучшие практики).В сомнении, обычно разумно придерживаться рекомендаций RFC 2818, раздел 3.1 (HTTP over TLS) по этому вопросу:

Если присутствует расширение subjectAltName типа dNSName,которые ДОЛЖНЫ использоваться в качестве личности.В противном случае ДОЛЖНО использоваться поле (наиболее конкретное) Common Name
в поле Subject сертификата.Хотя использование общего имени является существующей практикой, оно устарело, и сертификационным органам рекомендуется вместо этого использовать dNSName.

Сопоставление выполняется с использованием правил сопоставления, указанных в [RFC2459].Если в сертификате присутствует более одного идентификатора данного типа (например, более одного имени dNSName, совпадение в любом из набора считается приемлемым). Имена могут содержать подстановочный знак *, который считается соответствующим любомукомпонент доменного имени или фрагмент компонента.Например, .a.com соответствует foo.a.com, но не bar.foo.a.com.f .com соответствует foo.com, но не bar.com.

В некоторых случаях URI указывается в виде IP-адреса, а не имени хоста.В этом случае iPAddress subjectAltName должно присутствовать в сертификате
и должно точно соответствовать IP в URI.

( RFC 6125 явно не рекомендует использовать подстановочные сертификаты .)

По практическим причинам IP-адреса в сертификатах не идеальны (я не думаю, что многие коммерческие центры сертификации в любом случае сгенерируют такие сертификаты).Если вы можете, используйте расширение Subject Alternative Name, в противном случае достаточно ввести имя хоста в CN= RDN вашего Subject DN.В этом ответе есть примечания о том, как создать CSR / сертификат с SAN.В частности, возможно использование опции -ext в Java 7 keytool (например, -ext san=dns:www.example.com);обратите внимание, что хранилище ключей, сгенерированное keytool Java 7, должно использоваться и в предыдущих версиях JRE.

Кроме того, если у вас нет другого кода, кроме SSLContext.getDefault() (в этом случае вы также можете использовать значение по умолчанию SSLServerSocketFactory), вам необходимо указать хранилище ключей: JRE не имеетзначение по умолчанию для этого (в отличие от хранилища доверия).Это можно сделать с помощью javax.net.ssl.keyStore (и связанных системных свойств).В этом ответе есть больше по этой теме (например): https://stackoverflow.com/a/6341566/372643

0 голосов
/ 28 января 2012

Нет доступных сертификатов или ключей, соответствующих включенным комплектам шифров SSL

Эта ошибка означает:

Либо то, что закрытые ключи / сертификаты не подходят/ принятый набором шифров, который вы включили (это, скорее всего, означает длину короткого ключа) или что вы не настроили никаких сертификатов.

...