HAProxy SSL终端+;客户端证书验证+;curl/java客户端

HAProxy SSL终端+;客户端证书验证+;curl/java客户端,java,ssl,curl,haproxy,keytool,Java,Ssl,Curl,Haproxy,Keytool,我希望使用我自己的自签名证书在HAProxy上终止SSL,并使用我创建的客户端证书验证客户端访问 我通过以下方式创建服务器(也是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 以及: 在HAProxy,我配置: 绑定*:443 ssl crt/path

我希望使用我自己的自签名证书在HAProxy上终止SSL,并使用我创建的客户端证书验证客户端访问

我通过以下方式创建服务器(也是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
以及:

在HAProxy,我配置: 绑定*:443 ssl crt/path/server.pem ca file/path/ca.crt验证所需crt忽略所有错误

我以类似的方式创建客户端证书:

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对其进行签名(CA也是服务器证书,因此服务器可以识别一个简单的链)

要进行测试,我首先尝试使用服务器证书作为客户端证书:

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) 我想创建一个此服务器将要接受的客户端证书,并使用curl对其进行测试。 2) 我想使用keytool将这个证书和CA导入一个新的java密钥库/信任库,这样java(Jersey客户端)代码就可以访问相同的内容

我花了2天的时间在1/2上。 我很确定以前做过的人可以在5米内回答这个问题。我希望是这样


谢谢

1。创建客户端证书

错误:
openssl x509-req-signkey
创建自签名证书,根据定义,证书中的密钥(主题密钥)是同一密钥的公共密钥,其私有密钥对证书进行签名。证书文档(非req)很明显,它用签名密钥替换证书中以前的密钥。
-req
文档不太清晰,但它做了同样的事情;它将CSR中的主体名称(也作为颁发者)和
-signkey
中的密钥放入证书中。您使用了一个包含客户端名称的CSR,但使用了一个包含CA密钥的
-signkey
,生成了一个不可用的嵌合体

正确:要使用
x509
签署“子证书”(非自签名),请使用
-CA
以及可能的
-CAkey
,如文档中所述(或在安装了openssl doc的任何Unix上使用
man[where]x509
)。如果给定CA(由其DN定义)有或将有多个子证书,请使用序列号文件方案自动方便地分配序列号,或使用
-set_serial
手动分配唯一序列号(顺序是实现唯一性的最简单方法,但如果您喜欢另一种方法,也可以)

旁白:对于自签名CA(和服务器?!)证书,您不需要单独的
req-new
x509-req-signkey
步骤,您可以在一个
req-new-x509
中完成。有关
req
,请参阅文档/手册页。事实上,您不需要单独的
genrsa
步骤,
req-newkey[-nodes]-x509也可以这样做。注意:在OpenSSL 1.0.0+中,这会生成通用PKCS#8格式的密钥文件,而不是
genrsa
(和
rsa
)使用的“传统”PKCS#1格式;所有OpenSSL函数都可以接受其中一种,但其他一些函数可能不接受。特别是我上次检查时(不久前)使用akRSA服务器密钥解密SSL/TLS的Wireshark选项(还有其他选项)仅接受PKCS#1而不接受PKCS#8

2.在Java(泽西岛)中使用。请注意,任何进行客户端身份验证的SSL/TLS客户端(包括Java)都需要证书和私钥,并且在大多数情况下,证书使用的是您也需要的“链”或“中间”证书。有些人(咳嗽)Microsoft(咳嗽)鼓励您误解并忽略这一重要区别,但如果您尝试仅使用证书,则根本不起作用。另一方面,信任库条目只需要证书,几乎总是只需要根(CA)证书,并且通常必须只有证书。对于PKC来说,同一个人操作CA、服务器和客户端的情况有些不寻常

2a.可能只是转换为pkcs12。Java不直接支持密钥的openssl格式,但Java和openssl都支持PKCS#12(微软、Mozilla、苹果,可能还有其他公司也是如此)。因为您在
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

2018年更新:在编写此答案后,PKCS12的Java支持增加,因此不太需要转换为JKS。2017年秋季发布的8u60及以上版本仍然默认为密钥库类型JKS,但作为一项特殊功能(?)类型JKS实际上可以读取(但不能写入)PKCS12;请参阅并在文件
JRE/lib/security/java.security
中输入
keystore.type.compat
。2017年发布的Java9生成默认的密钥库类型PKCS12(如预期)读写PKCS12,虽然显式JKS不再读PKCS12。但是如果出于某种原因需要使用Java9进行转换,现在需要指定
-deststoretype JKS
,但不再需要指定
-srcstoretype PKCS12

谢谢!让我们重新开始,一笔勾销。我想创建一个CA、服务器证书和nd客户端证书。我不介意服务器证书(haproxy)是CA证书,但由于我正在深入研究这个问题,我想做最符合逻辑的事情。我希望curl和Java客户端使用客户端证书,并使用haproxy进行验证。实现这一点的最佳方法是什么?你能指定正确的步骤顺序吗?顺便说一句:找到了,我能够创建证书和curl。我即使能够将证书导入java密钥库,但java在ssl握手方面仍然失败。@JRun这是一个发生了重大变化的问题;这是一个判断问题,但我认为这比SE在回答问题时喜欢的变化更大,因为目标是任何有(原始)问题的人都能找到问题和答案
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
keytool -importkeystore -srckeystore client.p12 -srcstoretype pkcs12 -destkeystore client.jks