首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何让SSL peer_verify在Android上工作?

如何让SSL peer_verify在Android上工作?
EN

Stack Overflow用户
提问于 2014-08-12 07:09:43
回答 4查看 5.9K关注 0票数 14

我已经在Android上用openssl-1.0.1h成功构建了libcurl-7.36.0。我运行了一个示例代码来测试HTTPS连接。默认情况下,SSL_VERIFYPEER处于启用状态。Android上的证书路径是/system/etc/security/cacerts,所以我将CURLOPT_CAPATH设置为/system/etc/security/cacerts。

代码语言:javascript
复制
ls -l /system/etc/security/cacerts
-rw-r--r-- root     root         4767 2012-09-22 11:57 00673b5b.0
-rw-r--r-- root     root         4573 2012-09-22 11:57 03e16f6c.0
-rw-r--r-- root     root         5292 2012-09-22 11:57 08aef7bb.0
......

下面是我的代码片段。

代码语言:javascript
复制
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com:443");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);     // default
curl_easy_setopt(curl, CURLOPT_CAPATH, "/system/etc/security/cacerts");
curl_easy_perform(curl);

Curl总是返回一个错误:

代码语言:javascript
复制
== Info: SSL certificate problem: unable to get local issuer certificate  
== Info: Closing connection 0  
curl_easy_perform() failed: Peer certificate cannot be authenticated with given CA certificates

如果我从http://curl.haxx.se/docs/caextract.htmlcurl_easy_setopt(curl, CURLOPT_CAINFO, "path:/ca-bundle.crt")下载CA捆绑包文件ca-bundle.crt,它可以正常工作。

这是我的问题:有没有办法通过从/system/etc/security/cacerts读取证书而不手动下载CA包文件并指定CURLOPT_CAINFO来使SSL验证工作

EN

回答 4

Stack Overflow用户

发布于 2014-08-13 07:57:35

OpenSSL 0.9.x使用MD5文件名哈希。OpenSSL 1.0.x使用SHA-1作为文件名哈希。安卓使用的是MD5散列。Why old hash?

我尝试使用libcurl-7.36.0和openssl-0.9.8zb。它在启用了CURLOPT_SSL_VERIFYPEER的安卓系统上运行。

票数 4
EN

Stack Overflow用户

发布于 2014-08-12 14:40:45

编辑:我之前的答案是错误的。

CURLOPT_CAPATH应该指向使用c_hash工具为OpenSSL准备的目录。我不知道这是不是和Android提供的格式一样。

我找到了关于如何将新证书导入到最近的安卓系统的this description,它似乎指示了该目录中的文件格式与c_hash生成的文件格式略有不同……

票数 2
EN

Stack Overflow用户

发布于 2021-04-03 08:30:08

问题不在于Curl,而在于openSSL。

openssl 1.1.1x上的openssl 1.1.1x/crypto/x509/by_dir.c:

函数get_cert_by_subject(),它使用了与android不兼容的X509_NAME_hash()。

尝试修改openssl源中的by_dir.c:

代码语言:javascript
复制
#if defined(__ANDROID__)
  h = X509_NAME_hash_old(name);
#else
  h = X509_NAME_hash(name);
#endif

它应该可以解决这个问题。

补丁:

代码语言:javascript
复制
--- a/openssl-1.1.1k/crypto/x509/by_dir.c
+++ b/openssl-1.1.1k/crypto/x509/by_dir.c
@@ -247,7 +247,11 @@ static int get_cert_by_subject(X509_LOOKUP *xl, 
    
     ctx = (BY_DIR *)xl->method_data;

+#if defined(__ANDROID__)
+    h = X509_NAME_hash_old(name);
+#else
     h = X509_NAME_hash(name);
+#endif
     for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) {
         BY_DIR_ENTRY *ent;
         int idx;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25253823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档