r - 如何使用 SSL 在 R 中设置 httr cURL 句柄
问题描述
我在 SOAPUI 中有一个成功的 SOAP 请求,我正在尝试使用httr
包将其转换为 R 代码。在 SOAPUI 中,我对 SSL 设置所要做的就是为 KeyStore 提供一个指向 PKCS#12 文件的文件路径,然后为 PKCS#12 文件提供一个纯文本密码作为 KeyStore 密码。使用此设置,一切正常。
在 R 中,由于httr
uses curl
,据我了解,我需要.pem
从捆绑的 PKCS#12 文件中提取客户端 SSL 证书和 SSL 密钥作为两个文件。所以我使用以下 OpenSSL 命令提取了它们:
openssl pkcs12 -in "path to .p12 file" -passin pass:******** -clcerts -nokeys -out "path to new cert.pem"
openssl pkcs12 -in "path to .p12 file" -passin pass:******** -nodes -nocerts -out "path to new key.pem"
然后,在我的httr::POST
请求中,我包含了这个config
选项来指向.pem
文件,以便可以正确定义 curl 句柄(我只是临时设置ssl_verifypeer = F
,因此我可以消除由于 CA 捆绑包而出现错误的可能性):
config(ssl_verifypeer = F, sslcert = "path to new cert.pem", sslkey = "path to new key.pem")
但是,每当我运行httr::POST
请求时,都会出现以下错误:
Error in curl::curl_fetch_memory(url, handle = handle) :
schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs
when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows
System event log.
我不知道我在这里犯了什么错误,但我已经为此苦苦挣扎了好几个星期。这里的任何帮助都是救命稻草。
解决方案
您可以尝试以下方法:
# request made with certificate and key as plain text
res <- POST("the_url_goes_here",
config = config(sslcert = "certificate_path", sslkey = "key_goes_here_as_plain_text"),
verbose(data_out = F, data_in = F, info = T, ssl = F)) # this is quite helpful to debug if something goes wrong
# you can also read in the certificate separately
cert <- openssl::read_p12(file = "cert_path", password = "key_goes_here")
# since there are different type of certificates that are handled differently by curl, this table of options might be helpful as well
# it shows what is the corresponding parameter in httr to the one in curl
httr::httr_options()
# here is what a curl command could look like
curl --data "@name_of_the_file_goes_here.json" --cert "name_of_the_certificate_goes_here.pfx" --key "password_goes_here" https://url.com
pause
推荐阅读
- nginx - 如何在 nginx 中重写 IIS web.config 重写规则
- soap - 从 CF10 迁移到 CF2016 后如何使 SOAP 类型不强制小写?
- typescript - 如何生产和使用 Typescript 编写的多模块 NPM 包
- java - java数字模式打印问题
- javascript - jQuery 覆盖事件 preventDefault
- c# - 实体框架中的连接表不能隐式转换类型错误
- python - 如何有条件地将文件转换为 2D numpy 数组?
- php - Twitter REST API – 使用“tweet_mode=extended”参数时出现“无法验证您”错误
- css - 周选择器 CSS
- excel - 一次基于 LastRow 格式化范围列 S 到 Z