2015-05-25 3 views
3

Я хотел бы иметь завершение SSL на HAProxy, используя мои собственные самозаверяющие сертификаты, и проверять доступ клиентов с использованием созданных вами клиентских сертификатов.HAProxy SSL-окончание + проверка сертификата клиента + клиент curl/java

Я создаю сервер (который является также CA) сертификаты следующим образом:

openssl genrsa -out ca.key 1024 
openssl req -new -key ca.key -out ca.csr 
openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt 

и:

cat ca.crt ca.key > haproxy.pem 

в HAProxy, я устанавливаю: привязывать *: 443 SSL элт/path/server.pem ca-file /path/ca.crt проверить требуемый crt-ignore-err all

Я создаю клиентские сертификаты аналогичным образом:

openssl req -new -key client.key -out client.csr 
openssl x509 -req -days 365 -in client.csr -signkey ca.key -out client.crt 
cat client.crt client.key > client.pem 

Моя логика: Я создаю клиентский ключ, запрос на подпись сертификата для него, а затем подписываю его с помощью CA (который также является сертификатом сервера, поэтому существует простая цепочка, распознать).

Чтобы проверить, я сначала попробовать с сертификатом сервера в качестве клиента CERT:

curl https://my.service:443/ping -E ./haproxy.pem -k 
pong 

нормально, это работает. Теперь я пытаюсь с сертификатом клиента в качестве сертификата клиента:

curl https://my.service:443/ping -E ./client.pem -k 
curl: (58) unable to set private key file: './client.pem' type PEM 

Мой вопрос: 1) Я хотел бы создать сертификат клиента, что этот сервер будет accpet, и проверить его с помощью завиток. 2) Я хотел бы импортировать этот сертификат и CA в новое хранилище/доверительное хранилище java с помощью keytool, чтобы код Java (Jersey client) мог получить доступ к одному и тому же контенту.

Я провел 2 дня на 1/2. Я уверен, что кто-то, кто сделал это раньше, мог ответить на этот вопрос в 5 м. Или я надеюсь. :)

Спасибо!

ответ

2

1. создать клиент CERT

неправильно:openssl x509 -req -signkey создает самозаверенный сертификат, который по определению означает, что в, что сертификат (субъект ключа) ключ является публичной половины тот же ключ, чья частная половина подписывает сертификат. Документация для случая cert (not req) ясно, что он заменяет ключ, ранее в сертификате, ключом подписи. Документ -req менее ясен, но он делает то же самое; он помещает в cert имя субъекта из CSR, также как эмитент, и ключ от -signkey. Вы использовали CSR, содержащее имя клиента, но -signkey, содержащий ключ CA, создающий непригодную химеру.

право: подписать «ребенок» (не самозаверяющими) серт с x509, используйте -CA и, возможно, -CAkey, как описано в документации https://www.openssl.org/docs/apps/x509.html#SIGNING-OPTIONS (или man [where] x509 на любой Unix с установленной OpenSSL док).Если есть или будет более одного дочернего сертификата для данного ЦС (определенного его DN), либо используйте файловую схему серийного номера для автоматического и удобного назначения последовательных серийных номеров, либо используйте -set_serial, чтобы вручную назначать уникальные серийные номера (последовательный - это самый простой способ сделать уникальный, но если вы предпочитаете другой способ, это нормально).

в стороне: для самоподписного CA (и сервера ?!) CERT, вам не нужен отдельные req -new и x509 -req -signkey шагов, вы можете сделать это в одном req -new -x509. См. Doc/manpage для req. На самом деле вам не нужен отдельный шаг genrsa, req -newkey [-nodes] -x509 может это сделать. Одна нота: в OpenSSL 1.0.0+ это генерирует общий ключевой файл формата PKCS # 8 вместо «старого» формата PKCS # 1, который используется genrsarsa); все функции OpenSSL могут принимать либо, но некоторые другие вещи могут и не быть. В частности, последний раз я проверил (некоторое время назад) параметр Wireshark для дешифрования SSL/TLS с использованием ключа сервера для akRSA (есть и другие варианты), принятый только PKCS # 1, а не PKCS # 8.

2. использование на Java (Джерси). Обратите внимание, что any Клиент SSL/TLS, выполняющий аутентификацию клиента, включая Java, нуждается как в сертификате , так и в закрытом ключе, и в большинстве случаев сертификат использует также «цепочку» или «промежуточные» сертификаты, которые вам также нужны. Некоторые люди (кашель) Microsoft (кашель) заставляют вас неправильно понимать и игнорировать это важное различие, но если вы попытаетесь использовать только сертификат, он не будет работать вообще. С другой стороны, для входа доверенности требуется только сертификат, почти всегда только корень (CA), и обычно должен иметь только сертификат. Ваша ситуация, когда один и тот же человек управляет сервером CA ии, клиентом (-ами) является несколько необычным для PKC.

2a. возможно, просто конвертировать в pkcs12. Java напрямую не поддерживает формат (ы) openssl для ключей, но как Java, так и openssl поддерживают PKCS # 12 (а также Microsoft, Mozilla, Apple и, возможно, другие). Так как комбинированный ключ клиента и (лист) сертификат в client.pem сделать

openssl pkcs12 -export <client.pem -CA ca.crt [-name whatever] >client.p12 
# if you use separate key,cert files see the doc about -in and -inkey 

Java крипто (ОКО и JSSE) могут использовать эту PKCS # 12 в качестве хранилища ключей, если вы можете настроить «тип» хранилищу (как PKCS12). Значение по умолчанию SSLSocketFactory поддерживает это, а также другие приложения, которые я использовал, но я не использую Джерси и не знаю, что здесь делает. PKCS # 12 обычно не поддерживается для переноса «отдельных» сертификатов (без закрытого ключа), но в вашем случае сертификат CA для клиента равен также сертификат для сервера, поэтому он также будет работать в качестве вашего доверенного магазина ; в противном случае вам нужно будет импортировать сервер CA или серверный самоподписанный сертификат (только cert not privatekey) в доверительный магазин JKS (который может быть доверительным магазином по умолчанию в JRE/lib/security/[jsse] cacerts).

2b. возможно, последующее преобразование в JKS. Если Джерси не может использовать PKCS # 12 непосредственно, Java может преобразовать его в JKS, который любой вменяемый код Java может использовать, например:

keytool -importkeystore -srckeystore client.p12 -srcstoretype pkcs12 -destkeystore client.jks 

UPDATE в 2018 году: после того, как этот ответ был написан поддержка Java из PKCS12 увеличивается, что делает это реже необходимо преобразовать в JKS. 8u60 выпущен осенью 2017 года и до сих пор по умолчанию используется для хранения ключей типа JKS, но в качестве специальной функции (?) тип JKS может фактически читать (хотя и не писать) PKCS12; см. the release notes и товар keystore.type.compat в файле JRE/lib/security/java.security. Java9, выпущенный 2017, создает тип хранилища ключей PKCS12 по умолчанию, который (как и ожидалось) читает и записывает PKCS12, хотя явный JKS больше не читает PKCS12. Но если вам почему-то нужно конвертировать с Java9, теперь вам нужно указать -deststoretype jks, но больше не нужно указывать -srcstoretype pkcs12.

+0

Спасибо! Давайте начнем, протрите шифер чистой. Я хотел бы создать сертификат CA, серверный сертификат и клиентский сертификат. Я не возражаю, если сервер cert (haproxy) является сертификатом CA, но поскольку я погружаюсь в это, я хотел бы сделать наиболее логичную вещь, которая работает. Я хотел бы, чтобы завиток и клиент Java использовали клиентский сертификат и haproxy для его проверки. Какой был бы лучший способ достичь этого? Не могли бы вы указать правильную последовательность шагов? – JRun

+0

btw: Найдено https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.0/html/Web_Services_Security_Guide/files/i305191.html и https://access.redhat.com/documentation/en-US/ Red_Hat_JBoss_Fuse/6.0/html/Web_Services_Security_Guide/files/i382664.html, и я смог создать сертификаты и завитки. Я даже смог импортировать сертификат в хранилище ключей java, но все же Java терпит неудачу в ssl handshake. – JRun

+0

@JRun это существенно изменившийся вопрос; это решение, но я бы сказал, что это больше изменений, чем SE в ответном вопросе, потому что цель состоит в том, что * кто-либо * с (оригинальной) проблемой может найти вопрос и ответ. Поэтому я предлагаю вам задать * новый вопрос с тем, что вы сейчас делаете, и именно в чем проблема; «все еще не удается» бесполезно для решения проблемы. Это * я, возможно, лучше, если сертификат сервера не является сертификатом CA (более управляемым) и выдается одним и тем же CA (какой клиент нуждается в качестве проверки в любом случае). –