如何在 java 中进行相互 SSL 身份验证
How to do mutual SSL authentication in java
我想使用 java 代码进行相互 SSL 身份验证,但我没有成功 我有 key.pem
和 cert.pem
文件来进行身份验证 我已经尝试使用 Curl
curl -X POST -d '{ "Channel": "....}' -H "Content-Type: application/json" -H "Auth1: ***" -H "Auth2: ***" -k https://******/webservices/JSON/Default.aspx --cert "cert.pem" --key "Key.pem"
它运行良好,然后我尝试创建 java 程序参考
但是服务器 returns "CERT_MISSING"。我也试过这个 https://www.naschenweng.info/2018/02/01/java-mutual-ssl-authentication-2-way-ssl-authentication/ 这个代码创建 p12,crt 和 jks 文件,如上所述 link 但仍然得到同样的错误 "CERT_MISSING"。
这是有效的 NodeJS 示例:
var https = require("https");
var fs = require("fs");
var jsonData = {
"Channel": ....
}
var options = {
hostname: "****",
port: 443,
path: '/webservices/JSON/Default.aspx',
method: 'POST',
timeout: this.TimeOut,
headers: {'Content-Type':'application/json',"Auth1": "****","Auth2": "*****"},
json: true,
key: fs.readFileSync('Key.pem'),
cert: fs.readFileSync('cert.pem')
}
var req = https.request(options, function(res) {
res.on('data', function(data) {
var response = JSON.parse(data)
console.log(response)
req.end();
});
});
req.on('error', function(e) {
console.log("ERROR:");
})
req.write(JSON.stringify(jsonData));
req.end();
请帮帮我。
我只是想尝试回忆一些事情来完成你的清单。我无法举出完整的例子。我假设您同时控制客户端和服务器代码。或者至少是客户端代码,以及服务器配置的全面调整。
0-用wireshark看看是怎么回事。
1-确保您的服务器端在 serverhello 中发送了 accept-client-cert 或 requires-client-cert。 Curl 可能工作只是因为服务器不是 "requiring" 它,只是请求它。
2-确保服务器信任您的客户端证书签名者。这意味着如果您要在测试时制作自签名客户端证书,有时会破解服务器的证书颁发机构 (CA) 存储。
3-使用 wireshark,观察 ssl/tls 对话框并验证 clienthello 和 serverhello 是否符合预期(主要是如果 serverhello 执行 request/require 客户端身份验证并且客户端甚至尝试发送它)。如果有的话,那是很有教育意义的。
4-使用 jsse 教程自下而上编写琐碎的代码。使代码卡塔看到 keystore/castore 在那里,包含你所期望的。然后继续进行安全 [server]socketfactory 设置、keymanager、trustmanager 和 hostnameverifier(有或没有有人敢建议的后两者的危险绕过)。设置好这 4 个部分后,您就完成了 99%,您的 ssl/tls 套接字应该可以工作了。通常仍然会阻止您进行 ssl/tls 连接的少数事情是不兼容的密码套件或 tls 版本,或者具有无效日期的证书。由于您同时控制客户端和服务器,因此这应该不是问题。
5-一旦您可以信任您的客户端行为,您可以尝试连接到 https 服务器,例如 tomcat 或码头(我不知道您使用的是什么),并在 sslsocket 上发送粗略的 GET你 java 客户。
6-如果可行,现在您可以将 sslsocketfactory 传递给许多 http[s] 堆栈(smtp、httplient,甚至核心 jdk httpurlconnection)。
我认为您需要 "internediate-cert" 文件来将所有证书连接到一个 PEM 文件中,例如 cat "internediate-cert.pem" "codika_cert.pem" "Key.pem" > full-chain.keycert.pem
然后使用别名和密码生成 PKCS12(.p12) 密钥库 Like pkcs12 -export -in "full-chain.keycert.pem" -out full-chain.keycert.p12 -name alias -noiter -nomaciter
然后使用 full-chain.keycert.p12
作为密钥库和密码。它应该工作。
我想使用 java 代码进行相互 SSL 身份验证,但我没有成功 我有 key.pem
和 cert.pem
文件来进行身份验证 我已经尝试使用 Curl
curl -X POST -d '{ "Channel": "....}' -H "Content-Type: application/json" -H "Auth1: ***" -H "Auth2: ***" -k https://******/webservices/JSON/Default.aspx --cert "cert.pem" --key "Key.pem"
它运行良好,然后我尝试创建 java 程序参考
var https = require("https");
var fs = require("fs");
var jsonData = {
"Channel": ....
}
var options = {
hostname: "****",
port: 443,
path: '/webservices/JSON/Default.aspx',
method: 'POST',
timeout: this.TimeOut,
headers: {'Content-Type':'application/json',"Auth1": "****","Auth2": "*****"},
json: true,
key: fs.readFileSync('Key.pem'),
cert: fs.readFileSync('cert.pem')
}
var req = https.request(options, function(res) {
res.on('data', function(data) {
var response = JSON.parse(data)
console.log(response)
req.end();
});
});
req.on('error', function(e) {
console.log("ERROR:");
})
req.write(JSON.stringify(jsonData));
req.end();
请帮帮我。
我只是想尝试回忆一些事情来完成你的清单。我无法举出完整的例子。我假设您同时控制客户端和服务器代码。或者至少是客户端代码,以及服务器配置的全面调整。
0-用wireshark看看是怎么回事。
1-确保您的服务器端在 serverhello 中发送了 accept-client-cert 或 requires-client-cert。 Curl 可能工作只是因为服务器不是 "requiring" 它,只是请求它。
2-确保服务器信任您的客户端证书签名者。这意味着如果您要在测试时制作自签名客户端证书,有时会破解服务器的证书颁发机构 (CA) 存储。
3-使用 wireshark,观察 ssl/tls 对话框并验证 clienthello 和 serverhello 是否符合预期(主要是如果 serverhello 执行 request/require 客户端身份验证并且客户端甚至尝试发送它)。如果有的话,那是很有教育意义的。
4-使用 jsse 教程自下而上编写琐碎的代码。使代码卡塔看到 keystore/castore 在那里,包含你所期望的。然后继续进行安全 [server]socketfactory 设置、keymanager、trustmanager 和 hostnameverifier(有或没有有人敢建议的后两者的危险绕过)。设置好这 4 个部分后,您就完成了 99%,您的 ssl/tls 套接字应该可以工作了。通常仍然会阻止您进行 ssl/tls 连接的少数事情是不兼容的密码套件或 tls 版本,或者具有无效日期的证书。由于您同时控制客户端和服务器,因此这应该不是问题。
5-一旦您可以信任您的客户端行为,您可以尝试连接到 https 服务器,例如 tomcat 或码头(我不知道您使用的是什么),并在 sslsocket 上发送粗略的 GET你 java 客户。
6-如果可行,现在您可以将 sslsocketfactory 传递给许多 http[s] 堆栈(smtp、httplient,甚至核心 jdk httpurlconnection)。
我认为您需要 "internediate-cert" 文件来将所有证书连接到一个 PEM 文件中,例如 cat "internediate-cert.pem" "codika_cert.pem" "Key.pem" > full-chain.keycert.pem
然后使用别名和密码生成 PKCS12(.p12) 密钥库 Like pkcs12 -export -in "full-chain.keycert.pem" -out full-chain.keycert.p12 -name alias -noiter -nomaciter
然后使用 full-chain.keycert.p12
作为密钥库和密码。它应该工作。