r - RCurl 中的 TLS v1.1/TLS v1.2 支持

标签 r rcurl

ETA: Per https://github.com/hiratake55/RForcecom/issues/42, it looks like the author of the rforcecom package has updated rforcecom to use httr instead of RCurl (as of today, to be uploaded to CRAN tomorrow, 7/1/16), so my particular issue will be solved at that point. However, the general case (implementing TLS 1.1 / 1.2 in RCurl) may still be worth pursuing for other packages. Or everyone may just switch to the more recent curl package instead of RCurl.

背景:我已经使用 rforcecom 软件包与 Salesforce 通信几个月了。 Salesforce 最近禁用了对 TLS v1.0 的支持,并要求在其沙盒中使用 TLS v1.1 或更高版本;此更新将于 2017 年 3 月针对生产环境进行。

rforcecom 使用 RCurl 与 salesforce.com 服务器进行通信。一般使用curlPerform方法,它的实现是这样的(这个例子来自rforcecom.login.R):

h <- basicHeaderGatherer()
t <- basicTextGatherer()
URL <- paste(loginURL, rforcecom.api.getSoapEndpoint(apiVersion), sep="")
httpHeader <- c("SOAPAction"="login","Content-Type"="text/xml")
curlPerform(url=URL, httpheader=httpHeader, postfields=soapBody, headerfunction = h$update, writefunction = t$update, ssl.verifypeer=F)

正如我提到的,这对我来说已经有用了一段时间了。现在 Salesforce 已在沙盒上禁用 TLS v1.0,但它会失败并出现以下错误:

UNSUPPORTED_CLIENT: TLS 1.0 has been disabled in this organization. Please use TLS 1.1 or higher when connecting to Salesforce using https.

我已经修改并获取了(没有在包的本地副本中实现它,因为我没有足够的经验来执行此操作)对 RForcecom 登录模块的本地副本进行了更改,并且我发现通过实验,我可以通过添加 sslversion=SSLVERSION_TLSv1 成功指定 SSLVERSION 的任何现有枚举值。 , sslversion=SSLVERSION_SSLv3等到调用它的curlPerform选项。然而,所有这些都给了我与上面相同的错误。当我尝试使用 libcurl 中实现但未在 RCurl 中实现的选项之一( SSLVERSION_TLSv1.1SSLVERSION_TLSv1.2 )时,出现以下错误:

Error in merge(list(...), .opts) : object 'SSLVERSION_TLSv1.1' not found

或者:

Error in merge(list(...), .opts) : object 'SSLVERSION_TLSv1.2' not found

我已通过 curlVersion() 进行验证我的 libcurl 版本是 7.40.0,根据 https://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html确实支持这些选项。但是,我无法让 RCurl 识别它们。

此时,我正在寻找一种让 RCurl 使用 TLS v1.1 或 TLS v1.2 的方法,如果我能得到任何帮助,我将非常感激。对于我的问题中出现的任何问题,我深表歉意,因为这是我第一次自己提问,以前我总是能够通过阅读其他人的问题和答案来蒙混过关。

最佳答案

RCurl 是 libcurl 的接口(interface),它支持的内容取决于后者。您的 libcurl 可能是使用旧版本的 OpenSSL 构建的,该版本不支持 TLS v1.1 或 v.1.2。您可以像这样从 R 确定您的 SSL 版本:

RCurl::curlVersion()$ssl_version

我认为默认情况下(例如ssl选项CURL_SSLVERSION_DEFAULT),在SSL握手期间,服务器和客户端会就它们都支持的最新版本达成一致。要使其正常工作,您必须将 OpenSSL 更新到较新的版本,用它重新编译 libcurl 并重建 RCurl,以便它注册更新。

也就是说,您可以通过自己传递所需选项的整数值来强制执行 RCurl 中未定义的特定 ssl 版本。您要查找的数字可以从C enum中推断出来。定义于 the curl header file on GitHub :

enum {
  CURL_SSLVERSION_DEFAULT, // 0
  CURL_SSLVERSION_TLSv1, /* TLS 1.x */ // 1
  CURL_SSLVERSION_SSLv2, // 2
  CURL_SSLVERSION_SSLv3, // 3
  CURL_SSLVERSION_TLSv1_0, // 4
  CURL_SSLVERSION_TLSv1_1, // 5
  CURL_SSLVERSION_TLSv1_2, // 6
  CURL_SSLVERSION_TLSv1_3, // 7

  CURL_SSLVERSION_LAST /* never use, keep last */ // 8
};

例如:

# the data of you post request
nameValueList = list(data1 = "data1", data2 = "data2")

CURL_SSLVERSION_TLSv1_1 <- 5L
CURL_SSLVERSION_TLSv1_2 <- 6L

# TLS 1.1
opts <- RCurl::curlOptions(verbose = TRUE,
                           sslversion = CURL_SSLVERSION_TLSv1_1, ...)

# TLS 1.2
opts <- RCurl::curlOptions(verbose = TRUE,
                           sslversion = CURL_SSLVERSION_TLSv1_2, ...)

# finally, POST the data
RCurl::postForm(URL, .params = nameValueList, .opts = opts)

一般来说,这可能不是一个好的做法,因为 cURL 的作者可能会决定更改这些选项的值(尽管我认为机会很小)。

关于r - RCurl 中的 TLS v1.1/TLS v1.2 支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38130293/

相关文章:

r - 我可以计算行或列的最小值或最大值,也可以计算列的平均值,但无法计算行的平均值。为什么不?

r - 通过 anova 与 purrr 或 dplyr 比较模型

r - 如何使用循环调用列名:

R - 如何使用 rvest 或 rcurl 单击网页

Rcurl 与 http 数据发布

R:使用 RCurl 和 postForm 检索数据

r - 包 ‘randomForest ’ 不可用(对于 R 版本 4.0.2)

python - hist 中密度为 True 的 numpy.histogram 的维度

R - install_github 失败

r - 如何使用 header `postForm`