R:使用TLS/SSL安全下载数据

ant*_*nio 24 ssl curl r ssl-certificate rcurl

官方声明

在过去,基础R download.file()无法使用HTTPS协议,因此必须使用RCurl.自R 3.3.0起:

所有版本都支持https:URL,默认方法是download.file(),url()和使用它们的代码.遗憾的是,无法保证可以访问任何特定的https:URL....不同的访问方法可能允许不同的协议或使用私有证书包...

download.file() 帮助下仍然说道:

提供的包"RCurl"提供了更全面的URL下载工具.

其中(顺便提一下包括cookie和标题管理).

基于RCurl常见问题解答(查找"当我尝试通过https与URL进行交互时,我收到错误"),可以通过以下方式管理HTTPS URL:

getURL(url, cainfo="CA bundle")
Run Code Online (Sandbox Code Playgroud)

其中CA bundle是证书颁发机构捆绑文件的路径.一个这样的捆绑可以从卷曲网站本身获得:https:
//curl.haxx.se/ca/cacert.pem

当前状态

测试基于Windows平台

对于许多HTTPS网站的 download.file()工作原理如下:

download.file(url="https://www.google.com", destfile="google.html")
download.file(url="https://curl.haxx.se/ca/cacert.pem", destfile="cacert.pem")
Run Code Online (Sandbox Code Playgroud)

关于RCurl,使用cacert.pem上面下载的包,可能会出现错误:

library(RCurl)
getURL("https://www.google.com", cainfo = "cacert.pem")    
# Error in function (type, msg, asError = TRUE)  : 
#   SSL certificate problem: unable to get local issuer certificate
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只需删除对证书包的引用即可解决问题:

getURL("https://www.google.com")                      # works
getURL("https://www.google.com", ssl.verifypeer=TRUE) # works
Run Code Online (Sandbox Code Playgroud)

ssl.verifypeer = TRUE用于确保成功不是由于getURL()压制安全性.该论点记录在RCurl FAQ中.

但是,在其他情况下,连接失败:

getURL("https://curl.haxx.se/ca/cacert.pem")
# Error in function (type, msg, asError = TRUE)  : 
#  error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
Run Code Online (Sandbox Code Playgroud)

同样,使用以前下载的捆绑包:

getURL("https://curl.haxx.se/ca/cacert.pem", cainfo = "cacert.pem")
# Error in function (type, msg, asError = TRUE)  : 
#   error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
Run Code Online (Sandbox Code Playgroud)

即使在抑制安全性时也会发生同样的错误:

getURL("https://curl.haxx.se/ca/cacert.pem", ssl.verifypeer=FALSE)
# same error as above
Run Code Online (Sandbox Code Playgroud)

问题

  1. 如何在RCurl中正确使用HTTPS?
  2. 仅仅是文件下载(没有标题,cookie等),使用RCurl代替download.file()什么有什么好处?
  3. RCurl是否已经过时,我们应该选择卷曲吗?

更新

从Windows 10下的R版本3.4.1(2017-06-30)开始,该问题仍然存在.

Sat*_*tie 2

与 RCurl 捆绑的 openssl 目前有点旧,不支持 TLS v1.2

是的,curl包就可以了

或者您可以使用httr包,它是curl包的包装器

> library("httr")
> GET("https://curl.haxx.se/ca/cacert.pem",config(sslversion=6,ssl_verifypeer=1))
Response [https://curl.haxx.se/ca/cacert.pem]
  Date: 2017-08-16 17:07
  Status: 200
  Content-Type: application/x-pem-file
  Size: 256 kB
<BINARY BODY>
Run Code Online (Sandbox Code Playgroud)