RCurl中的TLS v1.1/TLS v1.2支持
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.RCurl中的TLS v1.1/TLS v1.2支持
背景:我一直在使用rforcecom软件包与Salesforce进行数月的交流。 Salesforce最近禁用了对TLS v1.0的支持,并且在其Sandbox中需要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_SSLv3
等添加到SSLVERSION中来成功指定SSLVERSION的任何现有枚举值curlPerform选项被调用。但是,所有这些都给了我与上面相同的错误。当我尝试使用的是libcurl中实现,但不是在RCurl(SSLVERSION_TLSv1.1
,SSLVERSION_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的一个接口,它支持什么取决于后者。有可能您的libcurl是使用较旧版本的OpenSSL构建的,它不支持TLS v1.1或v.1.2。你可以判断来自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)
在一般情况下,这可能不是一个很好的做法,因为卷曲的作者可以决定改变这些选项的价值(尽管我相信机会很低)。