Android 上的 libcurl CURLE_SSL_CACERT_BADFILE 错误

2023-12-30

所以我尝试将 libcurl 与 JNI 一起使用,但它返回 CURLE_SSL_CACERT_BADFILE 错误。这是我的代码。

JNI 端:

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    ((string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}


//jList is an array containing the certificate.

 Java_packageName_MainActivity_Test(JNIEnv *env, jobject thiz, jobject jList)
    {

        vector<string> certificatesPinning;

        // Convert jobject to jobjectArray
        // retrieve the java.util.List interface class
        jclass cList = env->FindClass("java/util/List");
        // retrieve the toArray method and invoke it
        jmethodID mToArray = env->GetMethodID(cList, "toArray", "()[Ljava/lang/Object;");
        jobjectArray stringArray = (jobjectArray)env->CallObjectMethod(jList, mToArray);

        // Add each certificate to the list
        int stringCount = (env)->GetArrayLength(stringArray);
        for (int i=0; i < stringCount; i++)
        {
            jstring certificateString = (jstring)(env)-> GetObjectArrayElement(stringArray, i);
            const char *cert = (env)->GetStringUTFChars(certificateString, 0);
            const jsize len = env->GetStringUTFLength(certificateString);

            string certificatePinningObj(cert,len);

            certificatesPinning.push_back(certificatePinningObj);
            (env)->ReleaseStringUTFChars( certificateString, cert);
        }

        string readBuffer;
        CURL *curl = curl_easy_init();
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
        curl_easy_setopt(curl, CURLOPT_URL, "https://theapi.com");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);// Fill the response in the readBuffer
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 120); // 120 s connect timeout
        curl_easy_setopt(curl, CURLOPT_ENCODING, GZIP);
        curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"der");

        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER , 1);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST , 2L);
        curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
        curl_easy_setopt(curl, CURLOPT_CAINFO,certificatesPinning[0].c_str());//buf


        CURLcode res;
        res = curl_easy_perform(curl);
        if(!readBuffer.empty())
        {
           printf("success \n");
        }
        else
        {
            printf("error \n");
        int a = (int)res;// this is 77 = CURLE_SSL_CACERT_BADFILE

        }
    }

JAVA端:

// Define the function
native void Test(ArrayList<String> certificates);

// Prepare the certificate
ArrayList<String> certificatesPinning = new ArrayList<String>();
certificatesPinning.add(saveCertPemFile());

// Call the function
Test(certificatesPinning);


 // Helpers
    private String saveCertPemFile()
    {
        Context context=getApplicationContext();
        String assetFileName="certificateName.der";

        if(context==null || !FileExistInAssets(assetFileName,context))
        {
            Log.i("TestActivity", "Context is null or asset file doesnt exist");
            return null;
        }
        //destination path is data/data/packagename
        String destPath=getApplicationContext().getApplicationInfo().dataDir;
        String CertFilePath =destPath + "/" +assetFileName;
        File file = new File(CertFilePath);
        if(file.exists())
        {
            //delete file
            file.delete();
        }
        //copy to internal storage
        if(CopyAssets(context,assetFileName,CertFilePath)==1) return CertFilePath;

        return CertFilePath=null;

    }

    private int CopyAssets(Context context,String assetFileName, String toPath)
    {
        AssetManager assetManager = context.getAssets();
        InputStream in = null;
        OutputStream out = null;
        try {
            in = assetManager.open(assetFileName);
            new File(toPath).createNewFile();
            out = new FileOutputStream(toPath);
            byte[] buffer = new byte[1024];
            int read;
            while ((read = in.read(buffer)) != -1)
            {
                out.write(buffer, 0, read);
            }
            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;
            return 1;
        } catch(Exception e) {
            Log.e("tag", "CopyAssets"+e.getMessage());

        }
        return 0;

    }

    private boolean FileExistInAssets(String fileName,Context context)
    {
        try {
            return Arrays.asList(context.getResources().getAssets().list("")).contains(fileName);
        } catch (IOException e) {
            // TODO Auto-generated catch block

            Log.e("tag", "FileExistInAssets"+e.getMessage());

        }
        return false;
    }

“certificateName.der”是存储在资产文件夹中的证书。

这是发送到 jni 的证书路径:

/data/data/packageName/certificateName.der

参考 http://coderclubs.com/questions/1728116/how-to-make-ssl-peer-verify-work-on-android


您还没有完全解释您在这里使用的内容,但我会的guess您下面有一个针对 OpenSSL 构建的 libcurl。这CURLOPT_CAINFO http://curl.haxx.se/libcurl/c/CURLOPT_CAINFO.html选项应该是标识 CA 证书包的文件名,使用 PEM 格式。该捆绑包是您可信 CA 的所有证书。

您的描述听起来好像您有一个 DER 文件,但您不能将 DER 用于 OpenSSL 的 CA 证书捆绑包。

获得像样的 CA 捆绑包的常见方法是下载Mozilla 发布的捆绑包的 PEM 版本 http://curl.haxx.se/docs/caextract.html包含在火狐浏览器中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 上的 libcurl CURLE_SSL_CACERT_BADFILE 错误 的相关文章

随机推荐

  • 如何有条件地显示 ASP.NET MVC Razor 中的字段?

    我对 C 和 ASP NET MVC Razor 非常陌生 如果该字段不为空 我想在我的视图中显示该字段 Code tr class hide td class editor label Html LabelFor model gt mod
  • 如何使用mysql全文获取连续单词的频率

    我有一个MyISAM表包含超过 200 万条记录 其中有一个FULLTEXT多列索引 给定一个搜索词 我想知道多少次它出现在每个记录的索引字段中 例如 当搜索 test 在下表中 其中有一个FULLTEXT两者的索引FREETEXT and
  • 显示第一类类型

    我有一个项目列表 每个项目都有一个类 并且该类在整个过程中重复 我只想显示每个类的第一个实例 只用 CSS 就可以实现吗 ul li class red red li li class red red li li class blue bl
  • 读取和解析大型 XML 文件的性能问题

    我有一个目录 其中包含几个大型 XML 文件 总大小约为 10 GB 有没有办法遍历包含 XML 文件的目录并读取 50 字节乘 50 字节并以高性能解析 XML 文件 func mdc Mdc Loadxml path string wg
  • 如何更改 R 中的时间序列(XTS 或 ZOO)?

    我是 stackoverflow 的新手 对 R 也相当陌生 但经过长时间的艰苦搜索 找不到以下问题的答案 我有许多数据文件 它们是温度与时间序列的关系 我将 CSV 作为 ZOO 对象导入 然后转换为 XTS 正确的文件如下所示 其中包含
  • 在 Protractor / E2E 测试中访问 $http 数据 (AngularJS)

    我有一堆进展顺利的单元测试 并且我已经开始将 Protractor E2E 测试添加到我的项目中 我在页面上测试交互元素做得很好 但在测试从浏览器发送的某些数据时遇到问题 例如 我想看看点击某个按钮是否会产生一个POST到某个端点 我使用以
  • 如何删除 BottomBar jetpack compose 中选定的椭圆形项目颜色

    我想删除所选项目后面的蓝色椭圆形颜色 我怎样才能做到这一点 NavigationBarItem selected selected onClick onClick icon if selected selectedIcon else ico
  • 如何使用具有 2 个或更多根的 try_files

    我看了一遍又一遍 发现没有这样的实现 我想知道我正在尝试的是否可能 我有 3 个提供静态内容的相对路径 Path1 usr local www style1 static Path2 usr local www style2 static
  • 视图控制器调用 awakeFromNib 两次

    我面临着这个奇怪的问题 我不确定我哪里出了问题 情况 我有一个 MainWindowController 类 它将加载要显示的正确笔尖 我创建了一个对象并将其更改为 IB 中的 MainWindowController 类 并将其与 Mai
  • 如何在 Keras 中找到错误的预测?

    我构建了一个 Keras 模型 用于从文本输入的原始输入中提取信息 我得到的准确度为 0 9869 我如何知道哪些训练数据导致准确性降低 我已将我正在使用的代码粘贴在下面 import numpy as np from keras mode
  • 如何遍历 json 响应?

    我有这个 json 响应 我正在尝试遍历它以获取天气条件 例如 湿度 和 温度 C 等 我尝试了一些方法但没有成功 data current condition cloudcover 50 humidity 44 observation t
  • 删除指针是否也会删除它所指向的内存?

    如果我有一个像这样的指针 int test new int 我创建了另一个指向的指针test像这样 int test2 test 然后我删除test2 delete test2 这是否意味着它将删除test以及 或者我必须打电话delete
  • 动画完成后所有 UIElement 都变得不可访问

    我正在尝试通过具有每个灯光坐标的 CGRect 数组来实现城市灯光动画 然后围绕这些 CGRect 创建 UIView 这个逻辑 感谢Darren https stackoverflow com users 1077601 darren用于
  • 如何以八度音程抑制命令的输出?

    在 Octave 中 我可以抑制或隐藏在行末尾添加分号的指令的输出 octave 1 gt exp 0 1 ans 1 0000 2 7183 octave 2 gt exp 0 1 octave 3 gt 现在 如果函数显示文本 例如使用
  • 遍历批处理文件中的文件夹和文件?

    这是我的情况 项目的目标是将一些附件迁移到另一个系统 这些附件将位于父文件夹中 比方说 Folder 0 see 这个问题的图 https serverfault com questions 147902 windows command l
  • PHP:简单的正则表达式来匹配长度?

    我正在创建一个注册系统 需要使用 REGEX 并且更喜欢 检查姓名 通行证等 到目前为止我得到的是 Check so numbers aren t first such as 00foobar preg match d a z0 9 iD
  • “@reify”有什么作用以及何时使用?

    我在用户体验设计金字塔教程 http docs pylonsproject org projects pyramid tutorials en latest humans creatingux step06 index html 我不太明白
  • 使用 Angular-cli 在 Angular2 中进行本地化

    Angular 有没有本地化工具2使用时Angular cli 我遇到了这个链接 https devblog dymel pl 2016 11 03 angular2 and i18n translate your app 从 11 月开始
  • 安装 AllegroServe

    我目前正在阅读 Peter Seibel 的书 Practical Common Lisp 正在阅读第 26 章 Web 编程 在第 366 页 它说 第一步是将 AllegroServe 代码加载到 Lisp 图像中 在 Allegro
  • Android 上的 libcurl CURLE_SSL_CACERT_BADFILE 错误

    所以我尝试将 libcurl 与 JNI 一起使用 但它返回 CURLE SSL CACERT BADFILE 错误 这是我的代码 JNI 端 static size t WriteCallback void contents size t