使用R的httr库发送SOAP请求时证书验证失败问题求助
使用R的httr库发送SOAP请求时.p12证书验证失败的解决方法
问题梳理
尝试用httr发送SOAP请求,使用.p12证书验证时遇到两个问题:
- 直接配置
sslcert和sslkey参数,返回{"operation" : "failed_cert"},证书验证失败 - 用
openssl读取.p12后传入请求,出现无法识别的二进制错误
核心问题分析
- 方案一错误:
httr中针对.p12格式证书,需要使用专门的ssl_p12和ssl_p12password配置项,而非sslcert+sslkey(这组参数适用于分离的.crt和.key文件) - 方案二错误:
openssl读取的证书/密钥是对象,httr要求传入PEM格式的字符串或文件路径,直接传入对象会导致二进制解析错误 - 额外问题:SOAP payload存在标签不匹配(
<userId>对应</endUserId>),可能导致服务端解析失败
修正后的解决方案
方案一:直接使用.p12文件配置请求
修正证书参数,同时修复payload标签错误:
library(httr) url <- 'https://www.b2b.preops.nm.eurocontrol.int/B2B_PREOPS/gateway/spec/26.0.0' # 修复标签不匹配问题,补充服务要求的命名空间 payload <- '<item:itemName xmlns:item="http://your-service-namespace"> <userId>myUserID</userId> <sendTime>2023-03-28 11:42:28</sendTime> <data> <type>NEW</type> </data> </item:itemName>' keystore <- "my_p12_file.p12" keystore_password <- "the_password" headers <- list(`Content-Type`="application/soap+xml;charset=UTF-8", SOAPAction = "Get") # 使用ssl_p12和ssl_p12password配置.p12证书 response <- POST(url, body = payload, add_headers(headers), config = config( ssl_p12 = keystore, ssl_p12password = keystore_password ), verbose( data_out = F, data_in = F, info = T, ssl = F) ) # 查看响应内容 cat(content(response, "text"))
方案二:通过openssl读取并转换为PEM格式
将openssl读取的证书和密钥导出为PEM字符串后传入请求:
library(httr) library(openssl) keystore <- "my_p12_file.p12" keystore_password <- "the_password" # 读取.p12并导出为PEM格式字符串 ps_key <- read_p12(keystore, keystore_password) cert_pem <- write_pem(ps_key$cert) key_pem <- write_pem(ps_key$key, password = keystore_password) url <- 'https://www.b2b.preops.nm.eurocontrol.int/B2B_PREOPS/gateway/spec/26.0.0' # 修正后的SOAP payload payload <- '<item:itemName xmlns:item="http://your-service-namespace"> <userId>myUserID</userId> <sendTime>2023-03-28 11:42:28</sendTime> <data> <type>NEW</type> </data> </item:itemName>' headers <- list(`Content-Type`="application/soap+xml;charset=UTF-8", SOAPAction = "Get") response <- POST(url, body = payload, add_headers(headers), config = config( sslcert = cert_pem, sslkey = key_pem, sslkey_password = keystore_password ), verbose( data_out = F, data_in = F, info = T, ssl = F) ) cat(content(response, "text"))
额外检查项
- 确认.p12文件路径正确,R进程有读取该文件的权限
- 验证证书密码的正确性,注意大小写、特殊字符
- 检查
SOAPAction值是否符合服务端要求,部分服务需要完整URL格式(如"http://eurocontrol.int/B2B/Get") - 确认SOAP payload的命名空间正确,服务端可能要求根节点声明对应的
xmlns:item属性
内容的提问来源于stack exchange,提问作者adl
相关产品推荐
相关产品推荐

