Https 编程

目录

  • 数字签名
  • 数字证书
  • Https 编程

数字签名

数字签名是非对称加密与数字摘要的组合应用

应用场景

  1. 校验用户身份(使用私钥签名,公钥校验,只要用公钥能校验通过,则该信息一定是私钥持有者发布的)
  2. 校验数据的完整性(用解密后的消息摘要跟原文的消息摘要进行对比)

签名过程

“发送报文时,发送方用一个哈希函数从报文文本中生成报文摘要,然后用自己的私人密钥对这个摘要进行加密,这个加密后的摘要将作为报文的数字签名和报文一起发送给接收方,接收方首先用与发送方一样的哈希函数从接收到的原始报文中计算出报文摘要,接着再用发送方的公用密钥来对报文附加的数字签名进行解密,如果这两个摘要相同、那么接收方就能确认该数字签名是发送方的。
数字签名有两种功效:一是能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。二是数字签名能确定消息的完整性。因为数字签名的特点是它代表了文件的特征,文件如果发生改变,数字摘要的值也将发生变化。不同的文件将得到不同的数字摘要。一次数字签名涉及到一个哈希函数、发送者的公钥、发送者的私钥。

Paste_Image.png

使用步骤

1. //获取signature 对象,初始化算法:MD2withRSA, MD5withRSA, or SHA1withRSA
2. Signature signature = Signature.getInstance("MD5withRSA");
3. //创建私钥(从磁盘上读取)
4. PrivateKey privateKey = (PrivateKey)SerializableUtil.readObject(
5. "haha.privateKey");
6. //使用私钥进行初始化
7. signature.initSign(privateKey);
8. //传入需要签名的数据
9. signature.update(content.getBytes());
10. //执行签名
11. byte[] sign = signature.sign();
12.
13. //创建公钥(从磁盘上读取)
14. PublicKey publicKey = (PublicKey) SerializableUtil.readObject(
15. "haha.publicKey");
16. //使用公钥进行初始化
17. signature.initVerify(publicKey);
18. //传入需要校验的数据(即上面的原文)
19. signature.update(content.getBytes());
20. //执行校验
21. boolean verify = signature.verify(sign);

小结

数字签名一般不单独使用,基本都是用在数字证书里实现SSL 通信协议。下面将学习的数字证书就是基于数字签名技术实现的。

数字证书

数字证书就是互联网通讯中标志通讯各方身份信息的一串数字,提供了一种在Internet 上验证通信实体身份的方式,数字证书不是数字身份证,而是身份认证机构盖在数字身份证上的一个章或印(或者说加在数字身份证上的一个签名)。它是由权威机构——CA 机构,又称为证书授权(Certificate Authority)中心发行的,人们可以在网上用它来识别对方的身份。

应用场景

1,交易者身份的确定性、不可否认性、不可修改性
2,对应用进行签名认证(例如Android 的apk)

数字证书格式

数字证书格式

数字证书的格式普遍采用的是X.509V3 国际标准,一个标准的X.509 数字证书包含以下一些内容:

证书的版本信息;
证书的序列号,每个证书都有一个唯一的证书序列号;
证书所使用的签名算法;
证书的发行机构名称,命名规则一般采用X.500 格式;
证书的有效期,通用的证书一般采用UTC 时间格式,它的计时范围为1950-2049;
证书所有人的名称,命名规则一般采用X.500 格式;
证书所有人的公开密钥;
证书发行者对证书的签名。

数字证书原理

数字证书原理

数字证书是安全领域里的终极武器,SSL 通信协议里最核心的东西就是数字证书。他涉及到前面提到的所有知识:对称加密、非对称加密、消息摘要、数字签名等。数字证书可以通过java 自带的KeyTool 工具生成,生成后的数字证书一般保管在KeyStore 里。KeyStore可以叫做秘钥仓库。
秘钥仓库可以保管3 种类型的数据:KeyStore.PrivateKeyEntry(非对称机密里的私钥)、KeyStore.SecretKeyEntry (对称加密里的秘钥)、KeyStore.TrustedCertificateEntry(受信任的证书)

Keytool 工具

路径:jre\bin\keytool.exe

Paste_Image.png

常用命令:

生成keypair
keytool -genkeypair
keytool -genkeypair -alias lisi(后面部分是为证书指定别名,否则采用默认的名称为mykey)
看看keystore 中有哪些项目:
keytool -list 或keytool -list -v
keytool -exportcert -alias lisi -file lisi.cer
生成可打印的证书:
keytool -exportcert -alias lisi -file lisi.cer –rfc
显示数字证书文件中的证书信息:
keytool -printcert -file lisi.cer
直接双击lisi.cer,用window 系统的内置程序打开lisi.cer

Android 的keystore 相关知识

debug 签名路径:user.android\debug.keystore

Paste_Image.png

debug.keystore 的别名(alias)及密码:
别名:androiddebugkey,密码:android
签名命令(jdk1.6):
jarsigner -verbose -keystore debug.keystore -signedjar 1signed.apk 1.apk androiddebugkey
签名命令(jdk1.7):
jarsigner -verbose -keystore debug.keystore -signedjar 1signed.apk 1.apk androiddebugkey -digestalg
SHA1 -sigalg MD5withRSA
优化命令:zipalign -v 4 1signed.apk 1signedaligned.apk
验证签名是否成功:jarsigner -verify 1signed.apk

补充

签名证书:

由权威颁发机构颁发给服务器或者个人用于证明自己身份的东西,默认客户端都是信任的。主要目的是用来加密和保证数据的完整性和不可抵赖性
例如根证书机构Symantec 颁发给百度的就是签名证书,是受信任的。

Paste_Image.png

自签名证书:

由服务器自己颁发给自己,用于证明自己身份的东西,非权威颁发机构发布,默认客户端都是不信任的,主要目的是用来加密和保证数据的完整性和不可抵赖性,与签名证书相同.
例如中铁集团(SRCA)办法给12306 的证书就是自签名证书,自己给自己颁发的。

Paste_Image.png

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即可,服务器出示的所有证书都不做校验,一律放行。

1. public static void main(String[] args) throws Exception {
2. //协议传输层安全TLS(transport layer secure)
3. SSLContext sslContext = SSLContext.getInstance("TLS");
4. //创建信任管理器(TrustManager 负责校验证书是否可信)
5. TrustManager[] tm = new TrustManager[]{new EmptyX509TrustManager()};
6. //使用自定义的信任管理器初始化SSL 上下文对象
7. sslContext.init(null, tm, null);
8. //设置全局的SSLSocketFactory 工厂(对所有ssl 链接都产生影响)
9. HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
10.
11. //URL url = new URL("https://www.baidu.com");
12. URL url = new URL("https://kyfw.12306.cn/otn/");
13. HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
14. InputStream in = conn.getInputStream();
15. System.out.println(Util.inputstream2String(in));
16. }
17.
18. /**
19. * 自定义一个什么都不做的信任管理器,所有证书都不做校验,一律放行
20. */
21. private static class EmptyX509TrustManager implements X509TrustManager{
22. @Override
23. public void checkClientTrusted(X509Certificate[] chain, String authType)
24. throws CertificateException {
25. }
26. @Override
27. public void checkServerTrusted(X509Certificate[] chain, String authType)
28. throws CertificateException {
29. }
30. @Override
31. public X509Certificate[] getAcceptedIssuers() {
32. return null;
33. }

解决方案2

12306 服务器出示的证书是中铁集团SRCA 给他颁发的,所以SRCA 的证书是能够识别12306 的证书的,所以只需要把SRCA 证书导入系统的KeyStore 里,之后交给TrustManagerFactory 进行初始化,则可把SRCA 添加至根证书认证机构,之后校验的时候,SRCA 对12306 证书校验时就能通过认证。
这种解决方案有两种使用方式:一是直接使用SRCA.cer 文件,二是使用改文件的RFC 格式数据,将其写在代码里。

1. //12306 证书的RFC 格式(注意要记得手动添加两个换行符)
2. private static final String CERT_12306_RFC = "-----BEGIN CERTIFICATE-----\n"
3. +
"MIICmjCCAgOgAwIBAgIIbyZr5/jKH6QwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ04xKTAn"
4. +
"BgNVBAoTIFNpbm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMB4X"
5. +
"DTA5MDUyNTA2NTYwMFoXDTI5MDUyMDA2NTYwMFowRzELMAkGA1UEBhMCQ04xKTAnBgNVBAoTIFNp"
6. +
"bm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMIGfMA0GCSqGSIb3"
7. +
"DQEBAQUAA4GNADCBiQKBgQDMpbNeb34p0GvLkZ6t72/OOba4mX2K/eZRWFfnuk8e5jKDH+9BgCb2"
8. +
"9bSotqPqTbxXWPxIOz8EjyUO3bfR5pQ8ovNTOlks2rS5BdMhoi4sUjCKi5ELiqtyww/XgY5iFqv6"
9. +
"D4Pw9QvOUcdRVSbPWo1DwMmH75It6pk/rARIFHEjWwIDAQABo4GOMIGLMB8GA1UdIwQYMBaAFHle"
10. +
"tne34lKDQ+3HUYhMY4UsAENYMAwGA1UdEwQFMAMBAf8wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDov"
11. +
"LzE5Mi4xNjguOS4xNDkvY3JsMS5jcmwwCwYDVR0PBAQDAgH+MB0GA1UdDgQWBBR5XrZ3t+JSg0Pt"
12. +
"x1GITGOFLABDWDANBgkqhkiG9w0BAQUFAAOBgQDGrAm2U/of1LbOnG2bnnQtgcVaBXiVJF8LKPaV"
13. +
"23XQ96HU8xfgSZMJS6U00WHAI7zp0q208RSUft9wDq9ee///VOhzR6Tebg9QfyPSohkBrhXQenvQ"
14. + "og555S+C3eJAAVeNCTeMS3N/M5hzBRJAoffn3qoYdAO1Q8bTguOi+2849A=="
15. + "-----END CERTIFICATE-----\n";
16. public static void main(String[] args) throws Exception {
17. // 使用传输层安全协议TLS(transport layer secure)
18. SSLContext sslContext = SSLContext.getInstance("TLS");
19. //使用SRCA.cer 文件的形式
20. //FileInputStream certInputStream = new FileInputStream(new File("srca.cer"));
21. //也可以通过RFC 字符串的形式使用证书
22. ByteArrayInputStream certInputStream = new
ByteArrayInputStream(CERT_12306_RFC.getBytes());
23. // 初始化keyStore,用来导入证书
24. KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
25. //参数null 表示使用系统默认keystore,也可使用其他keystore(需事先将srca.cer 证书导入
keystore 里)
26. keyStore.load(null);
27. //通过流创建一个证书
28. Certificate certificate = CertificateFactory.getInstance("X.509")
29. .generateCertificate(certInputStream);
30. // 把srca.cer 这个证书导入到KeyStore 里,别名叫做srca
31. keyStore.setCertificateEntry("srca", certificate);
32. // 设置使用keyStore 去进行证书校验
33. TrustManagerFactory trustManagerFactory = TrustManagerFactory
34. .getInstance(TrustManagerFactory.getDefaultAlgorithm());
35. trustManagerFactory.init(keyStore);
36. //用我们设定好的TrustManager 去做ssl 通信协议校验,即证书校验
37. sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
38. HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
39. .getSocketFactory());
40. URL url = new URL("https://kyfw.12306.cn/otn/");
41. HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
42. InputStream in = conn.getInputStream();
43. System.out.println(Util.inputstream2String(in));
44. }

Android 里的https 请求:

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

总结

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容