用于SSL身份验证的自签名证书和客户端密钥库

时间:2015-06-18 02:37:46

标签: java ssl certificate keystore keytool

我需要在服务器(XML硬件设备)上创建和安装自签名证书,以对 Java 客户端/应用程序进行SSL身份验证,通过其接口配置,可以设置< em> keystore ,即 .jks 。出于显而易见的原因,我只需要将此设置用于测试目的而不是生产。以下是我创建密钥库 PKCS12 类型)的方式:

1)生成私钥(对)

$> openssl genrsa -des3 -out private.key 1024

2)生成证书请求(需要吗?) - 我只将值设置为 CN

$> openssl req -new -key private.key -out request.csr

3)创建自签名证书

$> openssl x509 -req -days 365 -in request.csr -signkey private.key -out cert.crt

4)创建 PKCS12密钥库

$> openssl pkcs12 -export -in cert.crt -inkey private.key -out keystore.p12

5)创建客户端 JKS

$> keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -srcalias myalias -destkeystore client.jks -deststoretype jks -deststorepass <same pass as private key> -destalias myalias

当我在服务器/设备上安装keystore.p12,客户端 Java 应用程序上的client.jks,并发出请求时,我收到以下错误:

javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate

我是否从根本上忽略了有关证书和SSL身份验证的内容?

1 个答案:

答案 0 :(得分:1)

还没有答案,但是评论过于复杂,所以我稍后会开始编辑。

(SSL / TLS)服务器和客户端是否共享密钥(和证书)?好的开发和测试,因生产而异。作为一般规则,每个需要进行身份验证的独立系统都应该拥有自己的私钥和该密钥的证书(有时但很少有多个证书)。如果所涉及的系统(或更一般地说是所有系统)和它们之间的通信都在同一个管理员的控制之下,那么放松这个规则并且(重新)使用一个密钥+证书并不是真的很痛苦。由于使用的密钥+证书应始终(可重新)配置,因此这是您可以稍后更改的决定,如果结果是可取的或必要的话,甚至会更改几次。

证书是否应该自签名?通常适合开发和测试,因生产而异。同样,如果所有相关系统都由一个管理员控制,或者至少是相互了解的一组有限人员(例如一个组织的部门或办公室),则CA无需真正的安全性来验证身份和确定信任。一个考虑因素是服务器证书必须对证书中的域名(或使用该选项的IP地址)进行编码,因此更改它们(这在开发和测试中经常需要)意味着返回到新证书的CA,至少是轻微的麻烦,有时是延迟。

目前,您正在尝试为客户端和服务器共享一个密钥和自签名证书。虽然您可能希望稍后更改这些内容,但我建议您首先关注某些工作。同时改变几个相互关联的事物往往会引起混淆。

<强>&#34;提取&#34;证书?对于当前设置,使用一个(共享)密钥+证书(自签名),您已经拥有JKS中的密钥+证书,P12中的密钥+证书,以及相同的证书文件(cert.crt),所以你不需要提取任何东西。如果您(稍后)使用keytool为Java(客户端)端生成新密钥和自签名证书,是的,您需要提取该证书。 如果您获得现有密钥或新密钥的CA签名证书,可能需要提取根/锚,但您可能已经拥有它,请参阅下文。

需要信任哪些证书?客户端始终(在此处不相关的少数例外情况)在其信任库中需要服务器的。 s cert,当客户端身份验证(也称为双向或双向)用于您的情况时,服务器在其信任库中需要客户端证书的。在您当前的情况下,客户端和服务器使用相同的证书,因此双方都需要相同的锚点。

  • 对于自签名证书,主播必须证书本身 - 必须更改,通常是手动,合作伙伴证书随时更改。

  • 对于 CA颁发的证书,锚点可以和(始终?)应该是该CA的 root 证书; CA根通常是长期存在的(例如20年或更长时间),并且在合作伙伴/实体证书执行时不需要更改。

  • 如果您使用像Verisign或GoDaddy这样的众所周知的 CA,而不是使用自己运行的CA或者可能使用&#34; Joe的Dicount Liquor Store和证书颁发机构&#34;在您当地的红灯区,在某些系统中,知名CA 的根源可能已经安装,在这种情况下您不需要做任何事情。

客户端如何工作以信任服务器?您的Java客户端显然使用client.jks文件作为密钥库和信任库。这可以很容易地工作,因为Java使用一种可以包含两种数据的文件格式,并进一步将自己的密钥条目中的证书视为 一个受信任的证书(锚)。

服务器信任库怎么样?另一方面,对密钥库使用pkcs12格式的软件,或者至少导入密钥库条目的软件,有时(I&# 39;经常说)它的信任库不使用相同的格式,当然也不是相同的文件。事实上它 拒绝客户端使用它已经拥有的相同证书作为它自己的可能这意味着它不会将你给它的pkcs12视为信任库数据,虽然原则上可能不喜欢其他内容,例如缺少ExtendedKeyUsage扩展或撤销/状态数据不可用。

您无法识别或描述作为您服务器的设备,因此我只能猜测SSL / TLS服务器(尤其是嵌入式服务器)可以工作的无数方式。但是在您的设备中某处可能是一种将证书添加到其信任库的方法。另外它应该在某个地方有某种错误日志,它可能包含关于它是否只需要信任库中的锚点(这里是自签名证书)的其他信息,或者别的 - 假设你可以看到该日志没有SSL / TLS身份验证!

如果您可以在您的服务器/设备上提供(链接)文档,或者告诉我们它显示,提供和/或接受的内容,我可能会更具体。