本文目录一览:
- 1、一文弄懂关于证书,签名,ssl,android包签名机制。
- 2、❖ 自签名 SSL 证书(self-signed SSL certificate)
- 3、如何创建一个自签名的SSL证书
- 4、如何生成自签名双向认证证书 ssl
一文弄懂关于证书,签名,ssl,android包签名机制。
所有的概念都基于一个非常重要的基础:
rsa 非对称加密算法 :
先感受下几个概念
PKI。
PKI是公钥基础设施(Public Key Infrastructure) 包括PKI策略、软硬件系统、证书机构CA、注册机构RA、证书发布系统和PKI应用等。
我们关注就俩东西: PKCS 证书机构CA 。前者是定义加密算法,签名,证书相关的各种事情采用的协议。后者可以为我们颁发权威的证书。
PKCS :
PKCS(The Public-Key Cryptography Standards )是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。RSA算法可以做加密、解密、签名、验证,还有RSA的密钥对存储。这些都需要标准来规范,如何输入,如何输出,如何存储等。-描述文件ssl如何签名
PKCS。全称是公钥密码学标准, 目前共发布过 15 个标准,这些标准都是协议。总结一下 就是对加密算法,签名,证书协议的描述。下面列举一些常用的协议,这些协议在本文都会对应上。
这些协议具体的实现就体现在openssl等工具中, 以及jdk工具keytool jdk java第三方库bouncycastle。
比如用openssl 如何生成公/私钥(PKCS#1)、签名(PKCS#1 )、签名请求文件(KCS#10)、 带口令的私钥(PKCS#8)。 含私钥的证书(PKCS#12)、证书库(PKCS#12)-描述文件ssl如何签名
其中涉及到算法的基础协议PKCS#1等,由于涉及到密码学原理所以我们并不需要深究它,只要知道怎么做就可以了。
现实中我们要解决这样一种情况:
客户端和服务器之间的数据要进行加密。需要两个达成同一个对称秘钥加密才行,那么这个秘钥如何生成,并在两边都能拿到,并保证传输过程中不被泄露。 这就用到非对称加密了。 后续的传输,就能用这个 对称秘钥来加密和解密了。-描述文件ssl如何签名
还有这样一个问题:
就是客户端如何判断服务端是否是合法的服务端。这就需要服务端有个id来证明它,而这个id 就是证书,而且必须是权威机构颁发的才能算是合法的。
因为客户端即浏览器,认定证书合法的规则必须通过第三方来确认 即ca颁发的证书。否则就我可能进了一个假网站。
而这两个问题 都是ssl协议要解决的内容。
所以ssl协议做了两件事情,一是验证身份,二是协商对称秘钥,并安全的传输。 而实现这个过程的关键数据模型就是证书, 通过证书中的ca对证书的签名,实现了身份验证,通过证书中的公钥,实现对对称秘钥加密,从而实现数据保密。 其实还顺手做了一件事情就是通过解密签名比对hash,保证了数据完整性。-描述文件ssl如何签名
明白ssl协议 首先明白几个重要的概念:
证书: 顾名思义就是提供了一种在Internet上验证通信实体身份的方式,数字证书不是数字身份证,由权威公正的第三方机构,即CA(例如中国各地方的CA公司)中心签发的证书, 就是可以认定是合法身份的。客户端不需要证书。 证书是用来验证服务端的。-描述文件ssl如何签名
一般的证书都是x509格式证书,这是一种标准的证书,可以和其他证书类型互相转换。完整来说证书包含,证书的内容,包括 版本号, 证书序列号, hash算法, 发行者名称,有效期, 公钥算法,公钥,签名(证书原文以及原文hash一起签名)而这个内容以及格式 都是标准化的,即x509格式 是一种标准的格式。-描述文件ssl如何签名
签名: 就用私钥对一段数据进行加密,得到的密文。 这一段数据在证书的应用上就是 对证书原文+原文hash进行签名。
谁签的名,就是用谁的私钥进行加密。就像身份证一样, 合法的身份证我们都依据是政府签的,才不是假证, 那就是浏览器会有政府的公钥,通过校验(解密)签名,如果能够解密,就可以确定这个就是政府的签名。就对了。-描述文件ssl如何签名
hash算法 :对原始数据进行某种形式的信息提取,被提取出的信息就被称作原始数据的消息摘要。比如,MD5和SHA-1及其大量的变体。 hash算法具有不可逆性,无法从摘要中恢复出任何的原始消息。长度总是固定的。MD5算法摘要的消息有128个比特位,SHA-1算法摘要的消息最终有160比特位的输出。-描述文件ssl如何签名
ca机构: 权威证书颁发机构,浏览器存有ca的公钥,浏览器以此公钥来验证服务端证书的合法性。
证书的获取: 生成证书申请文件.csr(涉及到PKCS#10定义的规范)后向ca机构申请。 或者自己直接通过生成私钥就可以一步到位生成自签名证书。 自签名证书就是用自己的私钥来签名证书。
那么为了体现到 证书身份认证、数据完整、保密性三大特性 ,证书的简化模型可以认为包含以下两个要素:服务器公钥,ca的签名(被ca私钥加密过的证书原文+原文hash),
身份认证:
浏览器存有ca公钥,用ca公钥解密网站发给你的证书中的签名。如果能解密,说明该证书由ca颁发,证书合法。 否则浏览器就会报警告,问你是否信任这个证书,也就是这个网站。这时候的证书可以是任何人签发的,可以自己签发的。 但是中间人攻击。 完全伪造新的证书, 这就没有办法了。 所以还是信任证书的时候要谨慎。-描述文件ssl如何签名
数据完整:
如果你信任该证书的话,这时候就会用证书中的公钥去解密签名,如果是ca签发的证书,那么之前就已经通过ca的公钥去解密签名了。 然后得到证书hash,然后在浏览器重新对证书做hash,两者比对一致的话,说明证书数据没有被篡改。-描述文件ssl如何签名
保密性:
使用证书的公钥对对称秘钥加密保证传输安全,对称秘钥生成后,后续的传输会通过对称秘钥来在服务端和客户端的加解密。
那么ssl协议的具体过程就是:
4.网站接收浏览器发来的数据之后 使用自己的私钥校验签名,并对原文进行hash 与解密出的hash 做比对检查完整性。然后发送编码改变通知,服务器握手结束通知(所有内容做hash )。 发送给客户端校验。-描述文件ssl如何签名
5 客户端校验,校验成功后,之后就用 对称秘钥进行通信了。
总共的过程是 c-s-c- s-c 四次握手。
四次握手简单来说分别是:
1.请求获取证书
2.服务端返回证书,客户端验证了证书的合法性和完整性,同时生成了对称秘钥。
3.客户端把加密的 对称秘钥发给服务器。服务器检查真实性和完整性。
4.服务端返回握手结束通知,客户端再检查一次真实性和完整性。
前两次握手是明文, 后两次握手是密文。 所以都要检查身份真实性和数据完整性。
ca的作用:
ca起到一个权威中间人的角色,如果脱离了ca, 那么证书还是证书,还能加密,保证数据完整性。 但是无法应用在客户端去认定服务器身份合法这个场景下。
下面就详细说下 脱离了ca签发的证书的应用:
自签名证书:
证书如果没有权威机构的签名,就是没有权威机构给你签发身份证。 那么这时候身份认证的场景变了。
这时候的认证场景就变成了,不再是某个官方权威说了算,而是假设第一次碰到这个证书,会认为,这个证书与之捆绑的实体之间是合法的并做记录。如果当这个实体下次捆绑了另一个证书,那么就是非法的。
这种情况常用于android中安装和校验app的时候,会先假设第一次安装的是合法的应用,认定这个app证书中的公钥是合法的公钥。然后通过自签名的证书,校验签名,就能实现后续安装是否合法以及完整性。
android中的如何对app进行身份认定和不被篡改:
android系统在安装app时候会进行校验applicationId,applicationId 不同会认定为不同应用。相同应用,第二次安装会校验证书是否和之前app的证书相同,如果相同则两个包很可能来自同一个身份。 如果证书不同,也就是该包被另一个身份用自己的私钥重新签名过,就会拒绝安装。 然后通过公钥来解密签名,如果能解密,说明身份是ok的。否则拒绝安装。比对解密签名后的hash 与apk包内的cert.sf文件(该文件是apk内所有文件生成的hash文件)是否一致,如果相同则认定为没有被篡改。-描述文件ssl如何签名
android在提交应用商店的问题:
应用商店也会校验 后续的上传和第一次上传时的证书,以及类似上述的后续的一系列校验。防止合法的开发者平台被盗后,上传非法应用。
android在接入第三方sdk的问题:
接入第三方sdk 会提交applicationId 和 sha1 值。 这个sha1值就是对 证书原文的签名后的sha1,也就是证书指纹。这个证书是证书库里最初的那个证书(x509格式),而不是对apk签名后生成的证书(PKCS#7)。一般的证书签名的主体是证书原文本身,而对apk签名还额外会对apk所有文件生成的hash值文件(cert.sf)进行一次签名。-描述文件ssl如何签名
第三方平台会记录 applicationId 与sha1 的对应关系。 当有假冒app试图接入时候,由于会对app内的PKCS#7证书转换为原始的x509格式证书,重新生成sha1值,与用户提交sha1 比对, 如果相同则说明证书很可能是ok的。 因为sha1就是证书的指纹。 之后就会通过证书中的公钥来校验签名,从而最终确认身份合法性以及信息完整性。-描述文件ssl如何签名
第三方平台之所以需要用户去提交证书指纹sha1值,多了这一步,就意味着你的证书是可以更换的,一旦更换了证书,就必须提交新的指纹给我,然后我来做匹配。而应用商店没有这个功能, 一旦你的证书的私钥丢了, 那就必须重新建一个新的app。-描述文件ssl如何签名
总结来看证书的身份认定机制:
在ssl协议下,这种场景是 浏览器用于认定合法的服务器身份。 在自签名证书下,需要用户选择是否信任该证书。
在android app采用自签名证书的场景下, 证书起到了 假设第一次的证书合法,公钥合法,后续如果证书不一致或不能够完成签名校验,就是非法。
证书库:
证书库应该满足PKCS#12协议。 但是jdk提供了制作证书的工具keytool 可以生成keystore类型的证书库,后缀为jks。 keystore pk12可以通过keytool命令互相转换。-描述文件ssl如何签名
证书库是个证书的容器, 可以用来创建数字证书。 在keystore证书库中,所有的数字证书是以一条一条(采用别名alias区别)的形式存入证书库的。证书库中的证书格式为pk12,即包含私钥。 如果导出证书的话, 可以导出为x509不包含私钥的格式 或者pk12包含私钥的证书。 也可以也可以用-import参数加一个证书或证书链到信任证书。-描述文件ssl如何签名
android中一般都采用读取证书库的方式,通过证书库来创建一个证书,通过alias来区分。 所以在签名的时候,一个alias是一个证书,不同的alias是不同的证书,不要搞错了。
几个关系:
证书和非对称加密算法的关系:
证书代表一个身份的主体,包含了非对称秘钥体系中的公钥,以及用私钥对证书签名。这种组织结构,把非对称加密算法从加密的功能,拓宽到了用于身份认证,信息完整性上。这体现在了证书的作用。 本质还是利用了非对称加密算法的特性。-描述文件ssl如何签名
ssl协议和证书的关系。
因为证书解决了客户端对服务器的身份认证(自签名证书除外),同时也解决了加密,和信息完整性,所以ssl协议基于证书来实现。
❖ 自签名 SSL 证书(self-signed SSL certificate)
自签名的SSL证书制作极其简单,几句openssl命令即可生成一个密钥和证书。但是:
自签名证书在网络上是不可信的,但如果只是自己家里、局域网内测试,是没有问题的。因为现在很多应用全都强制要求是https,所以自己电脑、家里服务器也都必须装配ssl证书。不愿意花钱买第三方证书,就自己本机制作一个自签名证书,也是可以的。-描述文件ssl如何签名
参考:如何在Linux中创建SSL证书签名请求(CSR)
参考:创建并部署自签名的 SSL 证书到 Nginx
制作前须知:
在本机创建一个自签名(自己给自己签名)的SSL证书,都是用 openssl 命令。一般Mac/Ubuntu等都是默认装配的,安装的话也是类似 sudo apt-get install openssl ,很简单。-描述文件ssl如何签名
生成证书分为这四步:
生成证书:
此时 ~/.ssl/ 文件夹下只剩下两个文件,即私钥-公钥(证书)对:
然后就可以将两个文件应用到HTTPS网络连接了。
CSR请求文件的互动过程太慢,每次手输比较麻烦,一般会用 *.cnf 配置文件来自动完成所需要输入的个人信息等内容。
比如可以建立一个 ~/.ssl/CSR-Config.cnf ,内容格式如下:
生成CSR请求文件时候,就可以用 -config 参数引用这个配置文件而不用进入交互环节了,命令如下:
另外,由于上面是指定的域名为 ,随便写的。为了让本地能正常访问局域网内的服务器,需要在本地的 /etc/hosts 中将 指定为一个ip地址,如 192.168.1.101
无论如何,自签名证书都是不会被自动信任的。
所以服务器的证书,必须在每台客户端设备上手动导入或信任才行。
Chrome信任自签名证书:
打开: chrome://flags/#allow-insecure-localhost ,然后enable本地不安全证书。
Mac本机信任自签名证书:
从Chrome的红色警告图标上,直接拖拽到桌面,就把证书保存到桌面了。
然后双击,启动证书管理器,打开证书,点击上面有一个 Trust ,选择 Always trust 即可。
iOS信任自签名证书:
在Safari的地址栏,点击
因为自签名证书无论如何都不被信任,很麻烦。所以干脆用免费申请到的公网证书来局域网用,然后就能被Chrome完全认可。
方法就是,把第三方证书配置到nginx等服务器上。然后修改本地的 /etc/hosts 文件,将局域网内的ip映射为第三方证书所对应的网站,如 192.168.1.101 music.spotify.com 。这样的话,就完全没有报警提示了。-描述文件ssl如何签名
但是,也需要每台客户端都修改hosts才行。(iOS不能改)
所有客户端都改还是比较麻烦的,如果可以配置路由器的话,直接修改路由器的hosts,或者路由器上的转发,就能达到所有局域网内客户端都能访问了。
但是缺点是,局域网上配置的映射后,就不能访问那个真实网址 music.spotify.com 听歌了。
如何创建一个自签名的SSL证书
创建自签名证书的步骤
注意:以下步骤仅用于配置内部使用或测试需要的SSL证书。
第1步:生成私钥使用openssl工具生成一个RSA私钥
$ openssl genrsa -des3 -out server.key 2048
说明:生成rsa私钥,des3算法,2048位强度,server.key是秘钥文件名。
注意:生成私钥,需要提供一个至少4位的密码。
第2步:生成CSR(证书签名请求)生成私钥之后,便可以创建csr文件了。
此时可以有两种选择。理想情况下,可以将证书发送给证书颁发机构(CA),CA验证过请求者的身份之后,会出具签名证书(很贵)。另外,如果只是内部或者测试需求,也可以使用OpenSSL实现自签名,具体操作如下:-描述文件ssl如何签名
$ openssl req -new -key server.key -out server.csr
说明:需要依次输入国家,地区,城市,组织,组织单位,Common Name和Email。其中Common Name,可以写自己的名字或者域名,如果要支持https,Common Name应该与域名保持一致,否则会引起浏览器警告。-描述文件ssl如何签名
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:joyios
Organizational Unit Name (eg, section) []:info technology
Common Name (e.g. server FQDN or YOUR name) []:demo.joyios.com
Email Address []:liufan@joyios.com
第3步:删除私钥中的密码在第1步创建私钥的过程中,由于必须要指定一个密码。而这个密码会带来一个副作用,那就是在每次Apache启动Web服务器时,都会要求输入密码,这显然非常不方便。要删除私钥中的密码,操作如下:-描述文件ssl如何签名
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
第4步:生成自签名证书如果你不想花钱让CA签名,或者只是测试SSL的具体实现。那么,现在便可以着手生成一个自签名的证书了。
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
说明:crt上有证书持有人的信息,持有人的公钥,以及签署者的签名等信息。当用户安装了证书之后,便意味着信任了这份证书,同时拥有了其中的公钥。证书上会说明用途,例如服务器认证,客户端认证,或者签署其他证书。当系统收到一份新的证书的时候,证书会说明,是由谁签署的。如果这个签署者确实可以签署其他证书,并且收到证书上的签名和签署者的公钥可以对上的时候,系统就自动信任新的证书。-描述文件ssl如何签名
第5步:安装私钥和证书将私钥和证书文件复制到Apache的配置目录下即可,在Mac 10.10系统中,复制到/etc/apache2/目录中即可。
需要注意的是,在使用自签名证书时,浏览器会提示证书不受信任,如果你是对外网站使用,建议还是去CA机构申请可信的SSL证书,现在证书也很便宜,沃通CA超快SSL Pre才488元/年。
如何生成自签名双向认证证书 ssl
1.创建CA私钥: ca.key
2.创建根证书请求文件ca.csr:
这里需要填入配置信息:
3.自签根证书ca.cer:
4.【这一步可做可不做】生成p12格式根证书ca.p12(密码填写123456,之前ca.csr的密码,ps:这里输入的时候是不可见的输入完成后回车即可)
5.生成服务端私钥key server.key:
6.生成服务端请求文件 server.csr
填入证书配置信息:
server.csr
7.生成服务端证书server.cer(ca.cer,ca.key,servr.key,server.csr这4个生成服务端证书):
8.生成客户端key client.key:
9.生成客户端请求文件client.csr:
填入证书配置信息:
10.生成客户端证书 client.cer:
11.【可做可不做】生成客户端p12格式根证书client.p12(密码设置123456):
至此,证书就制作完毕了:
原因:请求没有带上ca证书,无法校验服务器的证书
解决方法1:
curl 加上-cacert ca证书 校验服务器证书
解决方法2:
curl 加上-k 可以不校验服务器证书。
网上给出的答复是:
Whatever method you use to generate the certificate and key files, the Common Name value used for the server and client certificates/keys must each differ from the Common Name value used for the CA certificate. Otherwise, the certificate and key files will not work for servers compiled using OpenSSL.-描述文件ssl如何签名
When OpenSSL prompts you for the Common Name for each certificate, use different names.
解决方案:
参考文档链接:,感谢作者CQ_TYL