【问题标题】:TLS v1.1 / TLS v1.2 support in RCurlRCurl 中的 TLS v1.1 / TLS v1.2 支持
【发布时间】:2016-06-30 18:01:27
【问题描述】:

ETA:根据https://github.com/hiratake55/RForcecom/issues/42,看起来 rforcecom 软件包的作者已将 rforcecom 更新为使用 httr 而不是 RCurl(从今天开始,明天 7/1/16 将上传到 CRAN),所以我特别关注届时问题将得到解决。但是,一般情况(在 RCurl 中实现 TLS 1.1 / 1.2)可能仍然值得其他包追求。或者每个人都可能只是切换到更新的 curl 包而不是 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 已在 Sandbox 上禁用 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_TLSv1sslversion=SSLVERSION_SSLv3 等添加到调用它的 curlPerform 选项来成功指定 SSLVERSION 的任何现有枚举值。但是,所有这些都给了我与上面相同的错误。当我尝试使用在 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 的方法,我非常感谢我能得到的任何帮助。对于我的问题的任何问题/问题,我深表歉意,因为这是我第一次问自己,我以前总是能够通过阅读其他人的问题和答案来蒙混过关。

【问题讨论】:

    标签: r rcurl


    【解决方案1】:

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

    RCurl::curlVersion()$ssl_version
    

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

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

    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 的作者可能会决定更改这些选项的值(尽管我认为机会很小)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-02
      • 2012-04-02
      • 2016-06-24
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      相关资源
      最近更新 更多