gpt4 book ai didi

android - 没有对等证书异常 - Volley 和具有自签名证书的 Android

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:43:53 27 4
gpt4 key购买 nike

我正在尝试让我的应用通过 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);
});

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

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();

当我运行我的 Node 客户端脚本时,它运行良好。另一方面,我用来检查 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 , 而且,当我使用 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

下面是我的 JavaCode...

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) {}
}

关于android - 没有对等证书异常 - Volley 和具有自签名证书的 Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26412417/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com