无对等证书例外 - Volley 和具有自签名证书的 Android

2024-05-11

我正在尝试让我的应用程序通过 https 与我的服务器通信。 由于我不想付费让受信任的 CA 签署我的服务器证书,解决方案是使用自签名证书。

因此,我创建了 caconfig.cnf,如下所示:

[ ca ]
default_ca              = CA_default                    # The default ca section

[ CA_default ]
dir                     = ./demoCA                      # top dir
database                = $dir/index.txt                # index file.
new_certs_dir           = $dir/newcerts                 # new certs dir

certificate             = $dir/cacert.pem               # The CA cert
serial                  = $dir/serial                   # serial no file
private_key             = $dir/private/cakey.pem        # CA private key
RANDFILE                = $dir/private/.rand            # random number file

default_days            = 365                           # how long to certify for
default_crl_days        = 30                            # how long before next CRL
default_md              = md5                           # md to use
policy                  = policy_any                    # default policy
email_in_dn             = no                            # Don't add the email into cert DN
name_opt                = ca_default                    # Subject name display option
cert_opt                = ca_default                    # Certificate display option
copy_extensions         = none                          # Don't copy extensions from request

[ policy_any ]
countryName             = optional
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

然后,我使用以下命令创建并签署了我的证书:

$ mkdir myCA myCA/private myCA/newcerts
$ echo "01" > myCA/serial
$ touch demoCA/index.txt

$ openssl genrsa -des3 -out myCA/private/cakey.pem 1024
$ openssl req -new -x509 -days 3650 -key myCA/private/cakey.pem -out myCA/cacert.pem

$ openssl req -sha1 -newkey rsa:2048 -keyout server-key.pem -out server-cert-req.pem -subj '/CN=myhost/' -nodes
$ openssl ca -config caconfig.cnf -in server-cert-req.pem -out server-cert.pem
$ openssl x509 -inform PEM -in cacert.pem -outform DER -out certificate.cer
$ rm server-cert-req.pem

在我的 Nodejs 服务器代码中,我创建了这样的 https 服务器:

var express = require('express');
var https = require('https');

var PORT = 443;
var app = express();

app.get('/', function (req, res) {
    res.send("Server is working");
});

var httpsOptions = {
    key: fs.readFileSync('server-key.pem'),
    cert: fs.readFileSync('server-cert.pem')
};

https.createServer(httpsOptions, app).listen(PORT, function() {
    console.log('%s: Node server started on port %d ...', Date(Date.now() ), PORT);
});

为了测试一切是否正确,我还创建了一个节点客户端脚本,它向我的服务器发出请求。这是我的节点客户端的代码:

var https = require('https');
var fs = require('fs');

var request = https.request({
    host: 'myhost',
    port: 443,
    path: '/',
    method: 'GET',
    rejectUnauthorized: true,

    // Once it is self signed, I'm using my server certificate (public key).
    ca: [fs.readFileSync('cacert.pem').toString()]
}, function(response) {
    response.on('data', function(data) {
        console.log(data.toString());
    });
});

request.on('error', function(err) {
    console.log(err);
})

request.end();

当我运行节点客户端脚本时,它运行良好。另一方面,我用来检查 Volley 如何与 https 配合使用的 Android Volley Examples 应用程序无法正常工作。下面,我将描述我为使其发挥作用而遵循的所有步骤。

我使用以下命令使用certificate.cer 文件创建了一个 .bks 文件:

keytool -importcert -v -trustcacerts -file "certificate.cer" -alias IntermediateCA -keystore "res/raw/my_keystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-146.jar" -storetype BKS -storepass mysecret

然后,我验证了证书是否已正确导入到 .bks 中,如下所示:

keytool -list -keystore "res/raw/my_keystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-146.jar" -storetype BKS -storepass mysecret

我得到以下输出,这意味着它是正确的:

Keystore type: BKS
Keystore provider: BC

Your keystore contains 1 entry

imeto_alias, Oct 16, 2014, trustedCertEntry, 
Certificate fingerprint (SHA1): 03:DC:A1:6A:9B:1D:AD:59:A9:9B:1F:C2:43:7E:80:07:3B:B6:BE:CB

我遇到过这个tutorial http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/,并且,由于我正在使用 Volley,所以我决定遵循它。因此,下面是我对示例项目所做的以下更改。

Got Volley from git clone https://android.googlesource.com/platform/frameworks/volley

Got Android Volley Examples project from git clone git://github.com/ogrebgr/android_volley_examples.git

Copied my_keystore.bks containing the self-signed public key in res/raw;

Opened Act_SsSslHttpClient in the examples project, found "R.raw.test" and replaced it with R.raw.my_keystore;

Found "new SslHttpClient(" and replaced the default password "test123″ with "mysecret";

Replaced "44400" with the HTTPS port of my server/virtualhost ("443"). (I could also remove this parameter since "443" is the default port;

Replaced "https://tp.bolyartech.com:44400/https_test.html" with my server URL.

Started the app, went to "HTTPS with self-signed cert", then "Execute HTTPS request"

但是,当我按下按钮时,出现以下异常:

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

下面是我的Java代码...

public class Act_SsSslHttpClient extends Activity {
    private TextView mTvResult;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act__ss_ssl_http_client);

        mTvResult = (TextView) findViewById(R.id.tv_result);

        Button btnSimpleRequest = (Button) findViewById(R.id.btn_simple_request);
        btnSimpleRequest.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                // Replace R.raw.test with your keystore 
                InputStream keyStore = getResources().openRawResource(R.raw.my_keystore);


                // Usually getting the request queue shall be in singleton like in {@seeAct_SimpleRequest}
                // Current approach is used just for brevity
                RequestQueue queue = Volley.newRequestQueue(Act_SsSslHttpClient.this,
                                     new ExtHttpClientStack(new SslHttpClient(keyStore,
                                         "mysecret")));

                StringRequest myReq = new StringRequest(Method.GET,
                                                    "https://myServerURL/",
                                                    createMyReqSuccessListener(),
                                                    createMyReqErrorListener());

                queue.add(myReq);
            }
        });
    }

...

}

有人知道解决办法吗? 谢谢。


我在测试环境中使用自签名证书。为了使其工作,我在 Application 类的 onCreate 方法中调用此方法。它使所有证书都被接受。它不是保存的,但用于测试目的是可以的。

@Override
public void onCreate() {
    nuke();
    super.onCreate();
}

public static void nuke() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                X509Certificate[] myTrustedAnchors = new X509Certificate[0];
                return myTrustedAnchors;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs,
                    String authType) {}

            @Override
            public void checkServerTrusted(X509Certificate[] certs,
                    String authType) {}
        } };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection
                .setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection
                .setDefaultHostnameVerifier(new HostnameVerifier() {

                    @Override
                    public boolean verify(String arg0, SSLSession arg1) {
                        return true;
                    }
                });
    } catch (Exception e) {}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无对等证书例外 - Volley 和具有自签名证书的 Android 的相关文章

随机推荐

  • Python Pandas:如何替换包含“?”的字符串

    我有一个 Python 2 7 Pandas Dataframe 如下所示 Id Title URL Id 1 Bruce Almighty https www youtube com watch v 5VGyTOGxyVA Id 2 Su
  • 如何使用 keycloak 强制每个客户端登录(最佳实践?)

    我们目前正在实施 keycloak 但我们面临着一个问题 我们不确定解决它的最佳方法是什么 我们有不同的网络应用程序使用单点登录 并且运行良好 我们遇到的问题是 当我们在一个 Web 应用程序中使用 sso 登录 然后在另一个 Web 应用
  • 验证 asp.net mvc 中的下拉列表

    in controller ViewBag Categories categoryRepository GetAllCategories ToList in view Html DropDownList Cat new SelectList
  • XAMPP apache 服务器在 Skype 安装后未启动

    我收到以下控制台日志 1 14 33 PM apache Possible problem detected 1 14 33 PM apache Port 80 in use by c program files x86 skype pho
  • 从纵向旋转到横向时的字体大小问题

    解决了它 webkit text size adjust 100 Prevent font scaling in landscape while allowing user zoom 从纵向旋转到横向时 我遇到了一个小的字体大小问题 在 s
  • 通过 :: 调用包中的函数是一个好习惯吗

    我正在编写一些 R 函数 这些函数在其他包中使用一些有用的函数 例如stringr and base64enc 不打电话好不好library or require 首先加载这些包但要使用 直接引用我需要的功能 比如stringr str m
  • 数组扩展以按值删除对象

    extension Array func removeObject
  • Silverlight WCF服务跨域问题

    我有一个 silverlight 应用程序 托管在 Intranet mydomain net 和一个 WCF 服务 webservices mydomain net 我需要跨站点策略文件吗 如果是这样 只允许从 Intranet mydo
  • 事务管理器未回滚 Spring Batch 作业

    我遇到一个挑战 我需要从 SQL Server 数据库读取 未处理 的数据 处理数据 然后有选择地更新 DB2 数据库中的两到六个表 然后将该数据标记为在 SQL Server 上的原始数据库中已处理 在任何时候 如果出现任何问题 我希望回
  • 在 C++ 中创建观察者设计模式的好方法

    我正在尝试用 C 实现观察者设计模式 如下所示 include
  • CAShapeLayer 路径在动画后消失 - 需要它留在同一个地方

    感谢 StackOverflow 上的一些帮助 我目前正在 CAShapeLayer 中对路径进行动画处理 以制作一个从移动精灵指向屏幕上另一个移动点的三角形 动画完成后 三角形就会从屏幕上消失 我使用的持续时间非常短 因为每个精灵每 0
  • SDL 鼠标位置调整大小后裁剪

    我在 SDL 中的鼠标位置上遇到了一些奇怪的行为 如果我将窗口大小调整得更大 则任一鼠标事件的 x y 位置似乎都限制为原始窗口的宽度和高度 如果我缺少一些函数调用来告诉 SDL 鼠标区域的大小已增加 应用程序的相关部分 void Resi
  • Laravel 所有会话 ID 与 Redis 驱动程序

    在我的应用程序中 我希望允许某些用户能够注销除他 她之外的所有其他用户 当会话驱动程序设置为文件时 我已经完成了此功能 但现在我使用 redis 作为会话驱动程序 并且我无法找到任何方法来列出所有当前会话 就像我在文件时所做的那样司机 问题
  • 如何使用字符串参数来区分命名空间或类型?

    我需要在 NET 2 0 C 脚本中获取一些 JSON 输出 目标是使用一种方法来输出我需要的所有 JSON 提要 所有模型都具有相同的 id 和 name 属性 因此我有大约 15 个命名空间 它们在这里具有相同的部分 简而言之 因为我使
  • 如何声明文本字段只能包含整数?

    在 swift 中 我试图创建一个文本字段 该文本字段将允许启用按钮 但仅当文本字段包含整数时 我怎样才能做到这一点 两件事情 指定键盘类型以仅显示数字键盘 所以 设置keyboardType to numberPad 然而 这还不足以阻止
  • Powershell 调用程序集委托

    我有一个用于过程控制应用程序的 dll 程序集 我在我的内部使用 load电源外壳 script 该DLL包含我需要使用的委托类型 委托名称是 X Y Delegate 我在该 DLL 中有另一个方法 应该这样调用 Method deleg
  • 具有动态调整大小的 CSS 精灵

    我决定为我的整个网站 30 个图像 创建一个精灵表 这样我就可以加载 1 个图像并仅加载参考位置 从而减少图像加载时间和服务器调用 我的问题 是否可以引用 sprite 表中的图像 然后将该图像调整为其父容器的 100 例如 SomeDiv
  • MyBatis 映射中的复合键

    我无法将组合键传递给 MyBatis
  • 未经编辑,无法在 pptx 中的 BarChart 中查看 Apache POI 更新的数据值

    我有一个 pptx 模板 它只有一张用于测试目的的幻灯片 该幻灯片有一个简单的条形图 我可以通过在 pptx 文件上双击条形图来编辑条形图 并且可以更改 Sheet1 条形图数据表 中的值 并且我可以立即在条形图中看到更改 现在 我尝试使用
  • 无对等证书例外 - Volley 和具有自签名证书的 Android

    我正在尝试让我的应用程序通过 https 与我的服务器通信 由于我不想付费让受信任的 CA 签署我的服务器证书 解决方案是使用自签名证书 因此 我创建了 caconfig cnf 如下所示 ca default ca CA default