Android 安全加密:Https编程详解

Android安全加密专题文章索引

    • Android安全加密:对称加密
    • Android安全加密:非对称加密
    • Android安全加密:消息摘要Message Digest
    • Android安全加密:数字签名和数字证书
    • Android安全加密:Https编程

以上学习所有内容,对称加密、非对称加密、消息摘要、数字签名等知识都是为了理解数字证书工作原理而作为一个预备知识。数字证书是密码学里的终极武器,是人类几千年历史总结的智慧的结晶,只有在明白了数字证书工作原理后,才能理解Https 协议的安全通讯机制。最终才能在SSL 开发过程中得心应手。

另外,对称加密和消息摘要这两个知识点是可以单独拿来使用的。

知识点串联:

数字证书使用到了以上学习的所有知识

  1. 对称加密与非对称加密结合使用实现了秘钥交换,之后通信双方使用该秘钥进行对称加密通信。
  2. 消息摘要与非对称加密实现了数字签名,根证书机构对目标证书进行签名,在校验的时候,根证书用公钥对其进行校验。若校验成功,则说明该证书是受信任的。
  3. Keytool 工具可以创建证书,之后交给根证书机构认证后直接使用自签名证书,还可以输出证书的RFC格式信息等。
  4. 数字签名技术实现了身份认证与数据完整性保证。
  5. 加密技术保证了数据的保密性,消息摘要算法保证了数据的完整性,对称加密的高效保证了数据处理的可靠性,数字签名技术保证了操作的不可否认性。

通过以上内容的学习,我们要能掌握以下知识点:

  1. 基础知识:bit 位、字节、字符、字符编码、进制转换、io
  2. 知道怎样在实际开发里怎样使用对称加密解决问题
  3. 知道对称加密、非对称加密、消息摘要、数字签名、数字证书是为了解决什么问题而出现的
  4. 了解SSL 通讯流程
  5. 实际开发里怎样请求Https 的接口

概述

SSL(Secure Sockets Layer 安全套接层),为网景公司(Netscape)所研发,用以保障在Internet 上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。一般通用之规格为40 bit 之安全标准,美国则已推出128 bit 之更高安全标准,但限制出境。只要3.0 版本以上之I.E.或Netscape 浏览器即可支持SSL。

TLS(Transport Layer Security 传输层安全),用于在两个通信应用程序之间提供保密性和数据完整性。TLS 是SSL 的标准化后的产物,有1.0 ,1.1 ,1.2 三个版本,默认使用1.0。TLS1.0 和SSL3.0 几乎没
有区别,事实上我们现在用的都是TLS,但因为历史上习惯了SSL 这个称呼。

SSL 通信简单图示:

SSL 通信详细图示:

当请求使用自签名证书的网站数据时,例如请求12306 的客运服务页面:https://kyfw.12306.cn/otn/,则会报下面的错误,原因是客户端的根认证机构不能识别该证书错误信息:unable to find valid certification path to requested target

解决方案1

一个证书可不可信,是由TrustManager 决定的,所以我们只需要自定义一个什么都不做的TrustManager即可,服务器出示的所有证书都不做校验,一律放行。

public static void main(String[] args) throws Exception {
//协议传输层安全TLS(transport layer secure)
SSLContext sslContext = SSLContext.getInstance("TLS");
//创建信任管理器(TrustManager 负责校验证书是否可信)
TrustManager[] tm = new TrustManager[]{new EmptyX509TrustManager()};
//使用自定义的信任管理器初始化SSL 上下文对象
sslContext.init(null, tm, null);
//设置全局的SSLSocketFactory 工厂(对所有ssl 链接都产生影响)
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

 //URL url = new URL("https://www.baidu.com");
 URL url = new URL("https://kyfw.12306.cn/otn/");
 HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
 InputStream in = conn.getInputStream();
 System.out.println(Util.inputstream2String(in));
 }

 /**
 * 自定义一个什么都不做的信任管理器,所有证书都不做校验,一律放行
 */
 private static class EmptyX509TrustManager implements X509TrustManager{
 @Override
 public void checkClientTrusted(X509Certificate[] chain, String authType)
 throws CertificateException {
 }

 @Override
 public void checkServerTrusted(X509Certificate[] chain, String authType)
 throws CertificateException {
 }

 @Override
 public X509Certificate[] getAcceptedIssuers() {
 return null;
 }
}

解决方案2

12306 服务器出示的证书是中铁集团SRCA 给他颁发的,所以SRCA 的证书是能够识别12306 的证书的,所以只需要把SRCA 证书导入系统的KeyStore 里,之后交给TrustManagerFactory 进行初始化,则可把SRCA 添加至根证书认证机构,之后校验的时候,SRCA 对12306 证书校验时就能通过认证。

这种解决方案有两种使用方式:一是直接使用SRCA.cer 文件,二是使用改文件的RFC 格式数据,将其写在代码里。

//12306 证书的RFC 格式(注意要记得手动添加两个换行符)
 private static final String CERT_12306_RFC = "-----BEGIN CERTIFICATE-----\n"+
"MIICmjCCAgOgAwIBAgIIbyZr5/jKH6QwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ04xKTAn"+
"BgNVBAoTIFNpbm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMB4X"+
"DTA5MDUyNTA2NTYwMFoXDTI5MDUyMDA2NTYwMFowRzELMAkGA1UEBhMCQ04xKTAnBgNVBAoTIFNp"+
"bm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMIGfMA0GCSqGSIb3"+
"DQEBAQUAA4GNADCBiQKBgQDMpbNeb34p0GvLkZ6t72/OOba4mX2K/eZRWFfnuk8e5jKDH+9BgCb2"+
"9bSotqPqTbxXWPxIOz8EjyUO3bfR5pQ8ovNTOlks2rS5BdMhoi4sUjCKi5ELiqtyww/XgY5iFqv6"+
"D4Pw9QvOUcdRVSbPWo1DwMmH75It6pk/rARIFHEjWwIDAQABo4GOMIGLMB8GA1UdIwQYMBaAFHle"+
"tne34lKDQ+3HUYhMY4UsAENYMAwGA1UdEwQFMAMBAf8wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDov"+
"LzE5Mi4xNjguOS4xNDkvY3JsMS5jcmwwCwYDVR0PBAQDAgH+MB0GA1UdDgQWBBR5XrZ3t+JSg0Pt"+
"x1GITGOFLABDWDANBgkqhkiG9w0BAQUFAAOBgQDGrAm2U/of1LbOnG2bnnQtgcVaBXiVJF8LKPaV"+
"23XQ96HU8xfgSZMJS6U00WHAI7zp0q208RSUft9wDq9ee///VOhzR6Tebg9QfyPSohkBrhXQenvQ"+
"og555S+C3eJAAVeNCTeMS3N/M5hzBRJAoffn3qoYdAO1Q8bTguOi+2849A=="+
"-----END CERTIFICATE-----\n";
 public static void main(String[] args) throws Exception {
 // 使用传输层安全协议TLS(transport layer secure)
 SSLContext sslContext = SSLContext.getInstance("TLS");
 //使用SRCA.cer 文件的形式

//FileInputStream certInputStream = new FileInputStream(new File("srca.cer"));
//也可以通过RFC 字符串的形式使用证书
ByteArrayInputStream certInputStream = new
ByteArrayInputStream(CERT_12306_RFC.getBytes());
// 初始化keyStore,用来导入证书
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
//参数null 表示使用系统默认keystore,也可使用其他keystore(需事先将srca.cer 证书导入
keystore 里)
keyStore.load(null);
//通过流创建一个证书
Certificate certificate = CertificateFactory.getInstance("X.509")
.generateCertificate(certInputStream);
// 把srca.cer 这个证书导入到KeyStore 里,别名叫做srca
keyStore.setCertificateEntry("srca", certificate);
// 设置使用keyStore 去进行证书校验
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
//用我们设定好的TrustManager 去做ssl 通信协议校验,即证书校验
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
.getSocketFactory());
URL url = new URL("https://kyfw.12306.cn/otn/");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
InputStream in = conn.getInputStream();
System.out.println(Util.inputstream2String(in));
}

Android 里的https 请求:

把scra.cer 文件考到assets 或raw 目录下,或者直接使用证书的RFC 格式,接下来的做法和java工程代码一样

//ByteArrayInputStream in = new ByteArrayInputStream("rfc".getBytes());
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
Certificate ca;
try {
 ca = cf.generateCertificate(caInput);
 System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
 caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);

SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);

URL url = new URL("https://certs.cac.washington.edu/CAtest/");
HttpsURLConnection urlConnection =
 (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);

双向证书验证

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);

SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.
 getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

//初始化keystore
KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
clientKeyStore.load(getAssets().open("client.bks"), "123456".toCharArray());

KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, "123456".toCharArray());

sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());

Nogotofail

网络流量安全测试工具,Google的开源项目:https://github.com/google/nogotofail

(0)

相关推荐

  • 深入讲解HTTPS中的加密算法

    HTTPS介绍 HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块.服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据. 用途两种:一种是建立一个信息通道,来保证数据传输的安全:另一种就是确认网站的真实性,凡是使用了 https 的网站,都可以通过点击浏览器地址栏的锁头标志来查看网站认证之后的真实信息,也可以通过 CA 机构颁发的安全签章来查询. 前言 密码学在计算机科学中使用非常广泛,HTTPS就是建立在密

  • nginx环境下配置ssl加密(单双向认证、部分https)

    nginx下配置ssl本来是很简单的,无论是去认证中心买SSL安全证书还是自签署证书,但最近公司OA的一个需求,得以有个机会实际折腾一番.一开始采用的是全站加密,所有访问http:80的请求强制转换(rewrite)到https,后来自动化测试结果说响应速度太慢,https比http慢慢30倍,心想怎么可能,鬼知道他们怎么测的.所以就试了一下部分页面https(不能只针对某类动态请求才加密)和双向认证.下面分节介绍. 默认nginx是没有安装ssl模块的,需要编译安装nginx时加入--with

  • 详解https 加密完整过程

    https加密完整过程 step1: "客户"向服务端发送一个通信请求 "客户"->"服务器":你好 step2: "服务器"向客户发送自己的数字证书.证书中有一个公钥用来加密信息,私钥由"服务器"持有 "服务器"->"客户":你好,我是服务器,这里是我的数字证书 step3: "客户"收到"服务器"的证书后,它会去

  • Android 安全加密:Https编程详解

    Android安全加密专题文章索引 Android安全加密:对称加密 Android安全加密:非对称加密 Android安全加密:消息摘要Message Digest Android安全加密:数字签名和数字证书 Android安全加密:Https编程 以上学习所有内容,对称加密.非对称加密.消息摘要.数字签名等知识都是为了理解数字证书工作原理而作为一个预备知识.数字证书是密码学里的终极武器,是人类几千年历史总结的智慧的结晶,只有在明白了数字证书工作原理后,才能理解Https 协议的安全通讯机制.

  • Android开发使用HttpURLConnection进行网络编程详解【附源码下载】

    本文实例讲述了Android开发使用HttpURLConnection进行网络编程.分享给大家供大家参考,具体如下: --HttpURLConnection URLConnection已经可以非常方便地与指定站点交换信息,URLConnection下还有一个子类:HttpURLConnection,HttpURLConnection在URLConnection的基础上进行改进,增加了一些用于操作HTTP资源的便捷方法. setRequestMethod(String):设置发送请求的方法 get

  • Android开发使用URLConnection进行网络编程详解

    本文实例讲述了Android开发使用URLConnection进行网络编程.分享给大家供大家参考,具体如下: URL的openConnection()方法将返回一个URLConnection,该对象表示应用程序和URL之间的通信连接,程序可以通过URLConnection实例向该URL发送请求,读取URL引用的资源.通常创建一个和URL的连接,并发送请求,读取此URL引用的资源. 需要如下步骤: a)通过调用URL对象openConnection()方法来创建URLConnection对象 b)

  • Android pdf viewer在android studio应用问题说明详解

    之前一直是做.NET开发的,最近需要弄一个新闻app,能力有限,只能借助HTML5 WebAPP+android studio来完成这项工作. android studio主要用WebView来加载发布好的WebApp,打包生产APP. 其中由于显示一些pdf文档,所以研究了一下,记录一下心得,同时也希望帮助到新手们. android 显示网络pdf,基本原理:先将pdf文件通过DownloadManager下载到手机sdk某个文件夹中,然后通过android-pdf-viewer插件进行显示.

  • sweet alert dialog 在android studio应用问题说明详解

    看到这个sweet-alert-dialog很亲切,因为前端开发本人用的提示就是这个js插件,java牛人很厉害,直接弄成一个java包插件,Good! 下面记录如何引用到工程,并使用: sweet-alert-dialog插件可以直接到github上下载 地址:https://github.com/pedant/sweet-alert-dialog 或者直接到发布好的页面下载: https://github.com/pedant/sweet-alert-dialog/releases 我下载的

  • Android原生音量控制实例详解

    本文主要涉及AudioService.还是基于5.1.1版本的代码. AudioService.java文件位于/framework/base/media/java/android/media/下. 音量控制是AudioService最重要的功能之一.先总结一下: AudioService音量管理的核心是VolumeStreamState.它保存了一个流类型所有的音量信息. VolumeStreamState保存了运行时的音量信息,而音量的生效则是在底层AudioFlinger完成的.所以进行音

  • NodeJS加密解密及node-rsa加密解密用法详解

    要用nodejs开发接口,实现远程调用,如果裸奔太危险了,就在网上找了一下nodejs的加密,感觉node-rsa挺不错的,下面来总结一下简单的rsa加密解密用法 初始化环境 新建一个文件夹 node-rsa-demo , 终端进入,运行下面命令初始化 cd node-rsa-demo npm init # 一路回车即可 npm install --save node-rsa 生成公钥私钥 在 node-rsa-demo 下新建一个文件 index.js 写上如下代码 var NodeRSA =

  • HTTPS 原理详解

    随着 HTTPS 建站的成本下降,现在大部分的网站都已经开始用上 HTTPS 协议.大家都知道 HTTPS 比 HTTP 安全,也听说过与 HTTPS 协议相关的概念有 SSL .非对称加密. CA证书等,但对于以下灵魂三拷问可能就答不上了: 1.为什么用了 HTTPS 就是安全的? 2.HTTPS 的底层原理如何实现? 3.用了 HTTPS 就一定安全吗? 本文将层层深入,从原理上把 HTTPS 的安全性讲透. HTTPS 的实现原理 大家可能都听说过 HTTPS 协议之所以是安全的是因为 H

  • Java使用Cipher类实现加密的过程详解

    一.先看一个简单加密,解密实现 1.1 加密 /** * content: 加密内容 * slatKey: 加密的盐,16位字符串 * vectorKey: 加密的向量,16位字符串 */ public String encrypt(String content, String slatKey, String vectorKey) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

  • 使用IntelliJ IDEA 配置安卓(Android)开发环境的教程详解(新手必看)

      上移动端的测试课,老师和同学们用的都是eclipse, 只有我一个人用的是idea(用了两款软件之后觉得IDEA更好),真的太难了,配置环境就只有一个人孤军奋战了,自己选择的路,爬都要爬完,害!   有大佬推荐我用Android studio,去了解了一下,这个软件也不错,考虑到已经用了IDEA那就用吧. 操作环境和基本配置 操作环境:Win 10 基本环境配置:Java 1.8 基本工具:IDEA(自行下载安装购买,支持正版!) 一.jdk的下载安装与配置 1.1下载安装 jdk的官网下载

随机推荐