问题描述
我正在尝试使用REST保证来进行一些需要SSL身份验证的API调用。我收到了:
例如,当我把所有这些放在邮递员,它可以正常工作。现在,我想在我的Java代码中使用它……这就是我遇到的问题。我看到人们使用单独的工具来导入密钥等,但是我想在代码中进行细化:)
我发现有人在使用它:
RestAssured.config = RestAssured.config().sslConfig(SSLConfig.sslConfig()
.trustStore(TRUST_STORE_PATH,TRUST_STORE_PASS).trustStoreType("JKS")
.keyStore(KEY_STORE_PATH,KEY_STORE_PASS).keystoreType("PKCS12"));
其中KEY_STORE_ *是P12文件+密码(?),而TRUST_STORE_ *是cert +密钥(?)。但是,这将导致错误“无效的密钥库格式”。我已使用openssl将.cert.pem文件转换为(binary / x509),但这并没有任何改变...我想念什么?我需要调用什么黑魔法才能使其在代码中运行?
评论给了我一个主意;可能.p12文件不是“适当的”密钥库。因此:我使用keytool将cert + key转换为JKS信任存储,并使用OpenSSL将.p12 +密码转换为.pkcs12密钥存储。
代码现在为:
RestAssured.config = RestAssured.config().sslConfig(SSLConfig.sslConfig()
.trustStore(JKS_PATH,JKS_PASS).trustStoreType("JKS")
.keyStore(PKCS12_PATH,PKCS12_PASS).keystoreType("PKCS12"));
RestAssured.useRelaxedHTTPSValidation();
我添加了useRelaxedHTTPSValiadion
调用,以确保我没有遇到奇怪的签名问题;也许我可以不用它,但是首先我要工作。编译并运行-进展!但是,现在当REST确保执行实际的POST:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
时,我会遇到一个错误。如前所述,我是在邮递员那里工作的,证书很好。但是以某种方式保证REST / Java的效果不好。
根据其中一项注释的要求,进行一些SSL调试/记录:
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.103 CEST|ServerHello.java:891|Consuming ServerHello handshake message (
"ServerHello": {
"server version" : "TLSv1.2","random" : <snip>,"session id" : "","cipher suite" : "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xC02F)","compression methods" : "00","extensions" : [
"renegotiation_info (65,281)": {
"renegotiated connection": [<no renegotiated connection>]
},"ec_point_formats (11)": {
"formats": [uncompressed]
},"extended_master_secret (23)": {
<empty>
}
]
}
)
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.103 CEST|SSLExtensions.java:173|Ignore unavailable extension: supported_versions
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.103 CEST|ServerHello.java:987|Negotiated protocol version: TLSv1.2
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.103 CEST|SSLExtensions.java:192|Consumed extension: renegotiation_info
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.104 CEST|SSLExtensions.java:173|Ignore unavailable extension: server_name
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.104 CEST|SSLExtensions.java:173|Ignore unavailable extension: max_fragment_length
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.104 CEST|SSLExtensions.java:173|Ignore unavailable extension: status_request
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.104 CEST|SSLExtensions.java:192|Consumed extension: ec_point_formats
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.104 CEST|SSLExtensions.java:173|Ignore unavailable extension: status_request_v2
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.104 CEST|SSLExtensions.java:192|Consumed extension: extended_master_secret
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.104 CEST|SSLExtensions.java:173|Ignore unavailable extension: session_ticket
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|SSLExtensions.java:163|Ignore unsupported extension: supported_versions
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|SSLExtensions.java:163|Ignore unsupported extension: key_share
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|SSLExtensions.java:192|Consumed extension: renegotiation_info
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|SSLExtensions.java:163|Ignore unsupported extension: pre_shared_key
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|ServerHello.java:1131|Locally assigned Session Id: <snip>
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|SSLExtensions.java:207|Ignore unavailable extension: server_name
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|SSLExtensions.java:207|Ignore unavailable extension: max_fragment_length
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.105 CEST|SSLExtensions.java:207|Ignore unavailable extension: status_request
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:215|Ignore impact of unsupported extension: ec_point_formats
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:207|Ignore unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:207|Ignore unavailable extension: status_request_v2
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:215|Ignore impact of unsupported extension: extended_master_secret
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:207|Ignore unavailable extension: session_ticket
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:207|Ignore unavailable extension: supported_versions
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:207|Ignore unavailable extension: key_share
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:215|Ignore impact of unsupported extension: renegotiation_info
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.106 CEST|SSLExtensions.java:207|Ignore unavailable extension: pre_shared_key
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.112 CEST|CertificateMessage.java:357|Consuming server Certificate handshake message (<snip>)
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.177 CEST|CertificateRequest.java:670|Consuming CertificateRequest handshake message (
"CertificateRequest": {
"certificate types": [rsa_sign,dss_sign,ecdsa_sign]
"supported signature algorithms": [rsa_pkcs1_sha256,dsa_sha256,ecdsa_secp256r1_sha256,rsa_pkcs1_sha384,dsa_sha384,ecdsa_secp384r1_sha384,rsa_pkcs1_sha512,dsa_sha512,ecdsa_secp521r1_sha512,rsa_pkcs1_sha1,dsa_sha1,ecdsa_sha1]
"certificate authorities": [<snip>]
}
)
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.179 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.179 CEST|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha256
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.180 CEST|X509Authentication.java:246|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.180 CEST|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha256
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.181 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.181 CEST|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp256r1_sha256
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.181 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.181 CEST|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha384
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.182 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.182 CEST|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp384r1_sha384
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.182 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.182 CEST|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha512
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.182 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.182 CEST|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_secp521r1_sha512
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.183 CEST|X509Authentication.java:246|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.183 CEST|CertificateRequest.java:764|Unavailable authentication scheme: rsa_pkcs1_sha1
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.183 CEST|X509Authentication.java:246|No X.509 cert selected for DSA
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.183 CEST|CertificateRequest.java:764|Unavailable authentication scheme: dsa_sha1
javax.net.ssl|ALL|01|main|2020-09-24 09:27:51.184 CEST|X509Authentication.java:246|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.184 CEST|CertificateRequest.java:764|Unavailable authentication scheme: ecdsa_sha1
javax.net.ssl|WARNING|01|main|2020-09-24 09:27:51.184 CEST|CertificateRequest.java:774|No available authentication scheme
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.184 CEST|ServerHellodone.java:151|Consuming ServerHellodone handshake message (
<empty>
)
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.184 CEST|CertificateMessage.java:290|No X.509 certificate for client authentication,use empty Certificate message instead
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.185 CEST|CertificateMessage.java:321|Produced client Certificate handshake message (
"Certificates": <empty list>
)
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.189 CEST|ECDHClientKeyExchange.java:400|Produced ECDHE ClientKeyExchange handshake message (
"ECDH ClientKeyExchange": {
"ecdh public": {
<snip>
},}
)
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.196 CEST|ChangeCipherSpec.java:115|Produced ChangeCipherSpec message
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.197 CEST|Finished.java:398|Produced client Finished handshake message (
"Finished": {
"verify data": {
<snip>
}'}
)
javax.net.ssl|DEBUG|01|main|2020-09-24 09:27:51.248 CEST|Alert.java:238|Received alert message (
"Alert": {
"level" : "fatal","description": "handshake_failure"
}
)
javax.net.ssl|ERROR|01|main|2020-09-24 09:27:51.251 CEST|TransportContext.java:361|Fatal (HANDSHAKE_FAILURE): Received fatal alert: handshake_failure
我认为这是罪魁祸首,No X.509 certificate for client authentication,use empty Certificate message instead
...这看起来很奇怪。
解决方法
您也可以在Java中使用邮递员进行操作。 RestAssured已经支持密钥库文件,并且还支持jks和pcsk12等不同格式。在您的情况下,将p12文件加载为密钥库对象时可以使用类型pcsk12。但是,对于其他文件,它不支持开箱即用的pem文件。您可以将这些文件合并到密钥库中,就像Kevin Boone所建议的一样,请参见此处以获取所有用于转换文件的选项:Openssl cheat sheet您还可以使用additional library - SSLContext Kickstart来加载和创建ssl配置并将其提供给RestAssured,请参见下面的示例。
X509ExtendedKeyManager keyManager = PemUtils.loadIdentityMaterial("cert.pem","key.pem","password".toCharArray());
SSLFactory sslFactory = SSLFactory.builder()
.withIdentityMaterial(keyManager)
.withTrustMaterial("truststore.p12","password".toCharArray(),"PKCS12")
.build();
RestAssured.config().sslConfig(SSLConfig.sslConfig().sslSocketFactory(new SSLSocketFactory(sslFactory.getSslContext())));
我以p12为示例信任材料,以pem文件为身份材料。