我已经在Android上用openssl-1.0.1h成功构建了libcurl-7.36.0。我运行了一个示例代码来测试HTTPS连接。默认情况下,SSL_VERIFYPEER处于启用状态。Android上的证书路径是/system/etc/security/cacerts,所以我将CURLOPT_CAPATH设置为/system/etc/security/cacerts。
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
......
下面是我的代码片段。
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总是返回一个错误:
== 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.html和curl_easy_setopt(curl, CURLOPT_CAINFO, "path:/ca-bundle.crt")
下载CA捆绑包文件ca-bundle.crt,它可以正常工作。
这是我的问题:有没有办法通过从/system/etc/security/cacerts
读取证书而不手动下载CA包文件并指定CURLOPT_CAINFO
来使SSL验证工作
发布于 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的安卓系统上运行。
发布于 2014-08-12 14:40:45
编辑:我之前的答案是错误的。
CURLOPT_CAPATH应该指向使用c_hash工具为OpenSSL准备的目录。我不知道这是不是和Android提供的格式一样。
我找到了关于如何将新证书导入到最近的安卓系统的this description,它似乎指示了该目录中的文件格式与c_hash生成的文件格式略有不同……
发布于 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:
#if defined(__ANDROID__)
h = X509_NAME_hash_old(name);
#else
h = X509_NAME_hash(name);
#endif
它应该可以解决这个问题。
补丁:
--- 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;
https://stackoverflow.com/questions/25253823
复制相似问题