Использование самоподписанного сертификата

Я просто пытаюсь понять SSL.

Я настроил сервер Jetty на своем локальном хосте и сгенерировал свой собственный сертификат, используя Кнопочный инструмент.

Теперь, когда я перехожу к https://localhost:8443/, я получаю сообщение об ошибке "Не могу доверять этому сертификату".

я использую

keytool -export -alias pongus -keystore хранилище ключей -file certfile.cer

Чтобы создать сертификат, который, я думаю, нужен клиенту для аутентификации на сервере. (Здесь я могу сильно ошибаться!)

У меня есть следующий рубиновый код:

require 'net/https'
require 'openssl'

require 'open-uri'

puts 'yay' if File.exists?('certfile.cer')

uri = URI.parse("https://localhost:8443/")
http_session = Net::HTTP.new(uri.host, uri.port)
http_session.use_ssl = true
http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER
http_session.ca_file = 'certfile.cer'
res = http_session.start do |http|
  # do some requests here
  http.get('/')
end

Это печатает «yay», поэтому файл certfile.cer существует.

Но я получаю ошибки

/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586 warning: can't set verify locations
/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586:in `connect': certificate verify failed (OpenSSL::SSL::SSLError)

Любые идеи, что я делаю неправильно?

ИЗМЕНИТЬ

Я хочу получить его, поэтому я гарантирую, что подключаюсь к нужному серверу, а сервер может гарантировать, что это я подключаюсь к нему, без каких-либо промежуточных манипуляций. Я разрабатываю как сервер, так и клиент.


person Mongus Pong    schedule 23.01.2010    source источник


Ответы (3)


Вашему клиенту нужен доступ к его закрытому ключу.

Вам не нужен закрытый ключ для проверки сертификата сервера. Все, что вам нужно, это сам сертификат, который содержит открытый ключ. Только сервер имеет закрытый ключ. Хорошо описано здесь http://www.helpbytes.co.uk/https.php и здесь http://www.verisign.com/ssl/ssl-information-center/how-ssl-security-works/

Моя рекомендация проста. Проверьте правильность вашего сертификата.

openssl x509 -text -in mycert.crt

Кроме того, если у вас есть доступ к серверу, вы можете явно проверить правильность (соответствие) сертификата и ключа (используемых в конфигурации httpd): http://kb.wisc.edu/middleware/page.php?id=4064 Обратите внимание, что это явная проверка, запущенная на сервере. Никогда не выдавайте закрытый ключ. Эту проверку может выполнить только администратор, чтобы убедиться, что httpd не был неправильно настроен.

(openssl x509 -noout -modulus -in server.pem | openssl md5 ;\
   openssl rsa -noout -modulus -in server.key | openssl md5) | uniq

Вы также можете отлаживать связь с SSL-сертификатом, используя стандартную команду openssl. Введите эту команду, затем подождите несколько секунд, а затем введите QUIT и нажмите Enter. Вы увидите сертификат, который отправляет сервер.

openssl s_client -connect your.server.com:443

Также попробуйте импортировать сертификат в свой браузер и получить доступ к ресурсу URL. Браузер может подтвердить это, нажав https (Firefox и Chrome). Затем вы увидите сам сертификат и информацию о его действительности.

Все вышесказанное касалось сертификата сервера. Это только одна часть проблемы. «Я подключаюсь к нужному серверу, и сервер может гарантировать, что это я подключаюсь к нему». На самом деле в приведенном выше коде вы проверяете только сертификат сервера. В настоящее время. Если вам нужен сертификат клиента (вторая часть вашего заявления), вам нужно это в Ruby:

File.open( "client_certificate.pem", 'rb' ) { |f| cert = f.read }
File.open( "client_key.pem", 'rb' ) { |f| key = f.read }
http_session.cert = OpenSSL::X509::Certificate.new(cert)
http_session.key = OpenSSL::PKey::RSA.new(key, nil)

Вот как следует использовать клиентский сертификат в Ruby. Если ваш закрытый ключ зашифрован паролем, просто передайте его вместо nil во втором аргументе конструктора RSA.

Я настоятельно рекомендую получить рабочий сертификат сервера (ваш код), а затем начать с клиентского сертификата. Обратите внимание, что вы сохраняете свой текущий код (ca_cert, константа проверки) и добавляете к нему указанные выше четыре строки.

Надеюсь это поможет.

person lzap    schedule 17.02.2011
comment
В любом случае вам НЕ НУЖЕН закрытый ключ на вашем клиенте. Никогда. Период. - person lzap; 17.02.2011
comment
Еще кое-что. Вы также можете ЭКСПОРТИРОВАТЬ сертификат с помощью Firefox или IE! Это очень просто. Получите доступ к странице и экспортируйте ее в файл PEM. Вы можете использовать это с Ruby. Я делал это несколько раз. Работает! - person lzap; 17.02.2011
comment
Неправильный. Вы просто не понимаете аутентификацию SSL-клиентов, а это то, что спрашивающий ясно заявил, что ему нужно. ... я думаю, что это то, что нужно клиенту для аутентификации на сервере ... а также комментарий в редактировании указывает на это. - person President James K. Polk; 18.02.2011
comment
Нет, Грег, ты не прав. Он не спрашивает об аутентификации клиента SSL, но столкнулся с проблемой проверки сертификата сервера SSL. Это другое. Атрибуты http_session.ca_file и http_session.verify_mode не используются для клиентских сертификатов SSL. - person lzap; 24.02.2011
comment
@Izap: Вам нужно прочитать, что он написал: ... поэтому я гарантирую, что подключаюсь к правильному серверу, и сервер может гарантировать, что это я подключаюсь к нему, .... Это называется аутентификацией клиента. - person President James K. Polk; 25.02.2011
comment
@GregS: Возможно, есть разница между тем, что он сказал, и тем, что он имел в виду. - person Jumbogram; 25.02.2011
comment
@Jumbogram: Согласен, здесь часто бывает проблема. Иногда приходится читать между строк. - person President James K. Polk; 26.02.2011
comment
Да, я пропустил часть, которую сервер может гарантировать, что это я подключаюсь к нему. Все, что я написал, все еще в порядке, кроме того, что это неправда. Ему нужны оба. Таким образом, в A ему нужен сертификат сервера без закрытого ключа, B ему нужен сертификат клиента, включая его закрытый ключ (конечно). Извините за путаницу, но я был уверен, что ему нужен только сертификат сервера (согласно его исходному коду). - person lzap; 28.02.2011
comment
Я добавил клиентскую часть в свой ответ. Я надеюсь, что это помогает. - person lzap; 28.02.2011

Вашему клиенту нужен доступ к его закрытому ключу. Закрытый ключ не находится в сертификате, сертификат содержит только открытый ключ. Извините, я не знаком с ruby, но распространенным методом является объединение закрытого ключа и сертификата в один файл PKCS # 12, также известный как p12, и передача его в криптобиблиотеку.

person President James K. Polk    schedule 24.01.2010
comment
Хороший, это хорошая информация, чтобы дать мне что-то, чтобы продолжать! Я вернусь к документации по keytool. Спасибо - person Mongus Pong; 24.01.2010
comment
Ruby принимает PEM. Нет необходимости в p12 и закрытом ключе. Это дыра в безопасности, чтобы выдать ПК :-) - person lzap; 17.02.2011
comment
@Izap: закрытого ключа нет, есть два: один для клиента и один для сервера. Вот почему я сказал, что клиенту нужен доступ к закрытому ключу ITS, а не серверу. - person President James K. Polk; 18.02.2011
comment
Грег, ты пытаешься смешать две вещи. Парень там попросил проверить сертификат сервера SSL против сертификата CA. Вы описываете авторизацию пользователя с сертификацией SSL. Это две разные вещи. Они могут жить вместе. - person lzap; 24.02.2011
comment
Извините, ему действительно нужен закрытый ключ, но только для клиентского сертификата. Для сертификата сервера закрытый ключ хранится на сервере. Смотрите мой пост выше. - person lzap; 28.02.2011

Изменять

http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER

to

http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE

Как только вы это сделаете, SSL будет работать правильно. Я использовал это несколько раз в своих средах разработки, всегда работает безупречно.

person Eugene    schedule 23.01.2010
comment
Спасибо, но я не хочу обходить проверку. . ;-) - person Mongus Pong; 24.01.2010
comment
Прошу прощения, что так долго не отвечал на это. Поскольку VERIFY_PEER пытается проверить сертификат на соответствие известному издателю SSL, вы должны использовать VERIFY_NONE, чтобы обойти эту проверку. Это не проверка сертификата как такового, а проверка эмитента сертификата. Поскольку самозаверяющие сертификаты не имеют известного эмитента, проверка не проходит. - person Eugene; 27.01.2010
comment
Это ДЕЙСТВИТЕЛЬНО ОПАСНО. Не делайте этого, если вы не знаете, что делаете. - person lzap; 17.02.2011