`
xyz_lmn
  • 浏览: 65501 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Android: Trusting SSL certificates

 
阅读更多

http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/

Two weeks ago I got the task to establish TLS secured connections via certificates to a service endpoint.
I thought it’s not a big deal, because the endpoint already uses an EV certificate from a trusted CA (SwissSign) in Switzerland. Therefore I shouldn’t have to worry that the certificate would be considered as untrusted so I don’t have to import it to the trusted certs in the Java key store etc.
FAIL! I’ve got a security exception, cert is not trusted. Same problem when I visit the website with the browser. Ok, that’s bad, SwissSign is not such a big player like thawte, so, it needs some time till it will be added to the android trusted CA list. But, when I visit thawte.com, their cert is also not trusted by android. WTF?
Windows Phone and iPhone trust my SwissSign CA and don’t complain.

So, let’s ask google, stackoverflow and the blogosphere. Found a lot of solutions how to disable certificate checking entirely.
Yeah, great, this will solve my problem, my connection will be “secure” and everyone will be able to intercept my connection and inject his own certificate.But I finally found the solution with help from other sites and some testing and debugging.

The Solution

The following main steps are required to achieve a secured connection from trusted Certification Authorities.

  1. Grab all required certificates (root and any intermediate CA’s)
  2. Create a keystore with keytool and the BouncyCastle provider and import the certs
  3. Load the keystore in your android app and use it for the secured connections
    • Don’t use the standardjava.net.ssl.HttpsURLConnection for the secure connection. Use theApache HttpClient (Version 4 atm) library, which is already built-in in android. It’s built on top of the java connection libraries and is, in my opinion, faster, bettermodularizedand easier to understand.

Step 1: Grab the certs

You have to obtain all certificates that build a chain from the endpoint certificate the whole way up to the Root CA. This means, any (if present) Intermediate CA certs and also the Root CA cert. You don’t need to obtain the endpoint certificate.
You can obtain those certs from the chain (if provided) included in the endpoint certificate or from the official site of the issuer (in my case SwissSign).

Ensure that you save the obtained certificates in the Base64 encoded X.509 format. The content should look similar to this:

1
2
3
-----BEGIN CERTIFICATE-----
MIIGqTC.....
-----END CERTIFICATE-----

Step 2: Create the keystore

Download the BouncyCastle Provider and store it to a known location.
Also ensure that you can invoke the keytool command (usually located under the bin folder of your JRE installation).

Now import the obtained certs (don’t import the endpoint cert) into a BouncyCastle formatted keystore.
I didn’t tested it, but I think the order of importing the certificates is important. This means, import the lowermost Intermediate CA certificate first and then all the way up to the Root CA certificate.

With the following command a new keystore (if not already present) with the password mysecret will be created and the Intermediate CA certificate will be imported. I also defined the BouncyCastle provider, where it can be found on my file system and the keystore format. Execute this command for each certificate in the chain.

1
keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/myKeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

Verify if the certificates were imported correctly into the keystore:

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

Should output the whole chain:

1
2
RootCA, 22.10.2010, trustedCertEntry,Thumbprint(MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93
IntermediateCA, 22.10.2010, trustedCertEntry,Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43

Now you can copy the keystore as a raw resource in your android app under res/raw/

Step 3: Use the keystore in your app

First of all we have to create a custom Apache HttpClient that uses our keystore for HTTPS connections:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Register for port 443 our SSLSocketFactory with our keystore
// to the ConnectionManager
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// Get an instance of the Bouncy Castle KeyStore format
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with
// your trusted certificates (root and any intermediate certs)
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
trusted.load(in, "mysecret".toCharArray());
} finally {
in.close();
}
// Pass the keystore to the SSLSocketFactory. The factory is responsible
// for the verification of the server certificate.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Hostname verification from certificate
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}

We have created our custom HttpClient, now we can just use it for secure connections. For example when we make a GET call to a REST resource.

1
2
3
4
5
6
// Instantiate the custom HttpClient
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Execute the GET call and obtain the response
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();

That’s it. Took me long to figure it out, hope this helps and saves you that time.

I really hope that the android platform will implement a better mechanism in future releases for defining which Certification Authorities should be trusted or not or just expand their own trusted CA list. If they don’t, I can’t believe they will get good acceptance from the business sector. Ok, you can control which certificates you want to trust in your app, but you still can’t add thawte as a trusted CA in the android keystore and your browser will always complain about an untrusted CA. The only way I know to eliminate this problem is to root your phone (very user friendly) and add your CA manually to the android keystore.

分享到:
评论

相关推荐

    kettle中调用restful接口时的SSL信任证书问题

    // Install the all-trusting host verifier HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; ...

    org.jasig.cas.client.util.CommonUtils

    SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // ...

    Reflections on Trusting Trust

    《Reflections on Trusting Trust》是一篇由肯·汤普森(Ken Thompson)撰写的图灵奖获奖演讲稿。该文深入探讨了在计算机领域中信任的概念,并提出了一个重要的观点:在考虑软件的安全性时,我们或许更应该关注开发...

    pokedex:https://trusting-meitner-c444fd.netlify.app

    在这个特定的案例中,该应用的源代码可以从提供的链接(https://trusting-meitner-c444fd.netlify.app-源码)获取。Netlify是一个流行的平台,用于托管、部署和管理Web应用程序,这表明这个pokedex应用是用现代Web...

    BlueHat Shanghai 2019PPT汇总(32份).zip - 渗透测试

    Betrayal of Reputation:Trusting the Untrustable Hardware and Software with Reputation.pdf Browser Script Engine Zero Days in 2018.pdf Discovering Vulnerabilities with Data Flow Sensitive Fuzzing.pdf ...

    Reflections on Trusting Trust-Thompson PDF

    Ken Thompson著作 Reprinted from Communication of the ACM, Vol. 27, No. 8, August 1984, pp. 761-763. Copyright © 1984, Association for Computing Machinery, Inc. Also appears in ACM Turing Award ...

    Web Security Mistakes - Trusting The Client

    标题“Web Security Mistakes - Trusting The Client”指出了Web安全中的一个常见错误:过分依赖客户端。这一错误可能会导致数据泄露、恶意代码执行以及安全漏洞。本文将从多个角度分析这一问题,包括客户端安全的...

    Betrayal of Reputation Trusting the Untrustable Hardware and So

    本次主题“Betrayal of Reputation — Trusting the Untrustable Hardware and Software with Reputation”聚焦于一个核心问题:我们是否应该基于声誉来信任硬件和软件的安全性?演讲者Seunghun Han是一位资深的安全...

    java安全手册指南

    #### 八、信任代码(Trusting the code) ##### 代码信任机制 - **代码签名**:使用数字签名技术对代码进行签名,确保代码来源可靠且未被篡改。 - **沙箱环境**:限制代码的执行范围,防止恶意代码损害系统。 - **...

    Betrayal of Reputation -- Trusting the Untrustable Hardware and

    在描述中提到的“Trusting the Untrustable”,意味着我们依赖的系统可能存在潜在的不安全因素,这些因素可能源于硬件的漏洞、软件的缺陷或是设计上的疏忽。这种信任的建立是基于对产品声誉的信念,但声誉并不能确保...

    信息安全_数据安全_Reflection_on_trusting_trust.pdf

    从标题《信息安全_数据安全_Reflection_on_trusting_trust.pdf》可以看出,本文将探讨数据安全领域中的信任问题,以及相关的云安全、漏洞挖掘、自动化、安全威胁和安全对抗等方面的知识。 在云安全方面,随着越来越...

    Azure可信在云端_Trusting_the_Cloud (1)1

    【Azure可信在云端】 在数字化转型的浪潮中,越来越多的企业选择将业务迁移至云端,以享受云计算带来的种种优势。Azure作为Microsoft提供的云服务平台,已成为众多企业的首选。公有云服务的市场规模持续扩大,预计...

    Docker镜像制作流程,包括docker安装、使用、镜像的制作、及使用

    docker commit trusting_rubin ubuntu:latest f5699a011052 八、镜像保存 可以通过以下命令将镜像保存到文件: docker save -o E:\myfile5.tar ubuntu:v5 九、镜像拷贝 制作完成后,可以将镜像拷贝到 U 盘中,...

    Trusting-Skynet:跟踪有关可解释机器学习的当前和过去工作的资源库

    信任天网 跟踪有关可解释机器学习的当前和过去作品的存储库。 有可用代码的可解释方法: 迈向具有常识的符号强化学习 代码: : 从策略学习中解耦特征提取 代码: : 可解释的强化学习的趣味性元素:了解特工...

    初中语文文摘生活尼布尔的祈祷文

    6. **信任与顺服**:"Trusting that He will make all things right if I surrender to His Will",表达的是对更高力量的信仰和顺服,认为只有在顺从神的旨意时,生活才能达到和谐。 7. **寻求幸福**:尼布尔的祈祷...

    英语中各类情绪的表达.docx

    - trusting(容易相信的):形容对人充满信任,不易怀疑。 - nurturing(悉心培养的):表示照料和培育,比如对孩子的关爱。 高级词汇: - relaxed(放松的):表示身心舒缓,无压力的状态。 - serene(宁静的):...

    2017高考英语改错经典十篇.docx

    第78题中,"have"和"trusting"并列,应将"trusting"改为"trust"。 4. 介词的使用: - "for"通常用于表示目的或原因,第79题中,"to help each other"是对"for"后面宾语的补充说明。 5. 固定搭配: - 第80题中的...

    profile_card_component

    截屏 链接解决方案URL: https : //github.com/miguel-tostado/profile_card_component 实时站点URL: https : //trusting-swanson-0821a3.netlify.app/ 我的过程 内置语义HTML5标记CSS自定义属性弹性盒 我学到的是...

    2018人教版英语必修四同步导学Unit4Section4PPT教学课件.pptx

    - **提供帮助**:"Thank you for trusting me, and I'd like to give you some advice." 3. **写作模板**: - **基础框架**:首先表达对对方问题的了解,然后提供一到三个实用建议,并期望对方能从中受益。 4. *...

    Smart Cities Cybersecurity and Privacy

    Smart Cities Cybersecurity and Privacy examines the latest research developments and their outcomes for safe, secure, and trusting smart cities residents. Smart cities improve the quality of life of ...

Global site tag (gtag.js) - Google Analytics