如何为gSoap OpenSSL Android应用程序存储和加载cacerts.pem 我正在使用一个使用OpenSSL的GSOAP的C++ Android应用程序。为了使OpenSSL能够验证服务器证书,我需要为它提供cacerts.pem文件的位置,否则所有HTTPS连接都会失败

如何为gSoap OpenSSL Android应用程序存储和加载cacerts.pem 我正在使用一个使用OpenSSL的GSOAP的C++ Android应用程序。为了使OpenSSL能够验证服务器证书,我需要为它提供cacerts.pem文件的位置,否则所有HTTPS连接都会失败,android,c++,openssl,gsoap,Android,C++,Openssl,Gsoap,我的问题是:在Android上存储和加载cacerts.pem的正确方法是什么 我可以通过将src/resources或res/raw/或assets/将cacerts.pem复制到APK根目录中。但是SSL\u CTX\u load\u verify\u locations(CTX,“cacerts.pem”,nullptr)找不到文件。如何使OpenSSL能够读取APK中的PEM文件 有没有办法将cacerts.pem存储为字符串缓冲区,从而避免在APK中携带它 我的应用程序需要与sha

我的问题是:在Android上存储和加载
cacerts.pem
的正确方法是什么

  • 我可以通过将
    src/resources
    res/raw/
    assets/
    cacerts.pem
    复制到APK根目录中。但是
    SSL\u CTX\u load\u verify\u locations(CTX,“cacerts.pem”,nullptr)
    找不到文件。如何使OpenSSL能够读取APK中的PEM文件

  • 有没有办法将
    cacerts.pem
    存储为字符串缓冲区,从而避免在APK中携带它

我的应用程序需要与sharepoint在线网站通话
(https://*.example.com/)

在Android上存储和加载cacerts.pem的正确方法是什么

必须加载验证主机证书所需的CA

您可以加载构建从主机到CA的路径所需的中间体,但这是可选的。配置良好的服务器将发送所需的中间证书,但并非所有证书都配置良好

您不需要加载
cacert.pem
或等效文件
cacert.pem
包含数百个认证,但只有一个是错误的


我是否需要以某种方式将cacerts.pem复制到.APK中(如何执行此操作?),并提供文件到SSL_CTX_load_verify_locations()的路径

不需要。您通常需要一个证书,这就是认证主机证书的CA。它可以是公共CA,如Comodo,也可以是组织内部的私有CA

您通常将其放在
res/
assets/
文件夹中。另请参见关于堆栈溢出的说明


有没有办法将cacerts.pem存储为字符串缓冲区,从而避免在.APK中携带它

是的,但是您可能需要获取字符串,将其写入文件系统,然后将该文件用于
SSL\u CTX\u load\u verify\u locations
。因此,最后,最好将其放在
res/
assets/


。。。sharepoint在线网站(https://*.example.com/)

主机名验证的一个重要注意事项。OpenSSL 1.0.2及更早版本不执行名称匹配。它执行其他常规检查,例如确保存在从最终实体证书(主机)到CA证书(信任根)的路径,并且证书未过期。但是它不执行主机名匹配

OpenSSL 1.1.0执行主机名匹配。它很快就会发布

作为权宜之计,您通常从库中取出缺少的代码,如
cURL
。cURL执行主机名匹配,Daniel Stenberg很乐意分享代码。我认为它位于
ssl.c
,如果内存对我有用的话


也可以在OpenSSL wiki上看到。

我终于可以让它工作了。我是一个完全的Android新手,所以在这里发布我的笔记,以防它们对像我这样的人有用

正如@jww所建议的,我将在发货前从cacerts.pem文件中删除所有不必要的证书

我有3个选项可以将cacerts.pem放入.APK

  • 在根目录下(将文件放在src\main\resources(不是src\main\res)中会导致它被放在apk的根目录下)
  • 在res\raw中(将文件放入src\main\res\raw中)
  • 在资产中(将文件放在src\main\assets中)
  • 在我的简短研究中,我找不到一种直接从APK根文件或从C++原始API读取RES原始文件的方法。所以我继续做第三个

    现在,使用“标准”C++函数(也就是如果我错了,请纠正我),也不能直接读取资产文件,所以我在java层中使用此代码将文件从资产文件夹复制到外部位置。

    试试看
    {
    AssetManager AssetManager=this.getAssets();
    File File=新文件(getFilesDir(),“cacerts.pem”);
    InputStream in=assetManager.open(“cacerts.pem”);
    OutputStream out=新文件OutputStream(文件);
    字节[]缓冲区=新字节[65536*2];
    int-read;
    while((read=in.read(buffer))!=-1){
    输出。写入(缓冲区,0,读取);
    }
    in.close();
    out.flush();
    out.close();
    }
    捕获(例外e)
    {
    }
    

    在此之后,我将这个文件位置传递给C++代码,并能够调用这个调用< /p>

    SSL\u CTX\u load\u verify\u位置(CTX,“/data/user/0/com.company.app/files/cacerts.pem”,空)
    
    注意:这不是最终的生产代码。现阶段只是概念证明。请随时指出您看到的任何错误或建议


    注意:有一段时间openssl仍然无法读取该文件,因此我使用ifstream文件(“/data…/cacerts.pem”)验证了该文件是否正确创建并可用,并且它就在那里。该错误后来以某种方式自行解决。

    如果您提供服务器名称和服务端口,我们可以提供您所需的更多详细信息。例如,我们可以说,“您需要证书X”,而不是含糊不清的“…CA需要验证主机的那个…”。谢谢jww。我的应用程序需要与sharepoint.com对话。我使用的是gSOAP,它需要将.pem文件位置传递给openssl。我理解我应该从.pem文件中删除所有其他认证。我唯一的开放性问题是,为什么SSL\u CTX\u load\u verify\u位置在APK根目录中存在“cacerts.pem”时失败。另请参阅和。