文中很多地方用到了网友的资源,谢谢你们。知识来源于网络,回馈于网络。
在现实世界中,没有人愿意裸奔;在互联网世界里也一样。数据在互联网中传播,要解决3+1个问题。分别为数据防偷窥,防篡改(完整性),防伪冒。还有+1问题就是身份认证。
二) 解决上述3个问题的办法
只要加好密,将明文加密得到密文,就可以解决防偷窥。别人拿到密文,也不知道你的真实内容。加密算法别人去研究,我们使用就行了。加密方式有2种(长话短说),对称加密和非对称加密。
加密和解密秘钥相同,即为对称加密。
优点:效率高,安全性好。
缺点:需要在网上分发秘钥,网上分发秘钥又不安全。
加密和解密秘钥不相同,即为非对称加密。非对称加密方式分别有公钥和私钥。公钥公诸于天下,谁都知道。私钥只要产生秘钥对的人知道,不能泄露。
重点:
拿公钥加密得到的密文,只能拿对应私钥才能解密密文。拿私钥对信息进行签名,只能拿对应的公钥进行验证签名。
公钥作用:只能加密明文,验证私钥的签名。
私钥作用:只能解密公钥加密的密文,对明文进行签名。
优点:公钥随便发;可进行单向安全数据传递,私钥可进行数字签名进行身份认证(防伪冒)。
缺点:效率低,不适合进行大量数据加密。
这个问题是信息完整性问题,我发送的123,接收方一定要收到123。不可多,不可少,不可变。解决这问题就是采用摘要技术,其实摘要算法是一种不可逆加密算法。
我们经常使用md5sum file 来查看文件的md5值。使用md5值来确认两个文件是否是一样的。计算md5值就是对信息进行摘要的过程。摘要算法有很多,摘要算法要有如下特性才能满足验证信息完整性的需求。
防碰撞:
就是不同的内容生成的摘要要不同,相同的内容生成摘要要相同。绝对的无碰撞是不可能的,只是规律还未被发现。Md5和sha1碰撞规律已经被人找到了,所以不能做摘要技术。
不可逆:
不要算个摘要被人把内容推到出来了,岂不是十分尴尬。
使用签名技术即可解决信息伪冒问题。和现实世界一样,在文件上你签一个字,画个押。这个签字和押就代表你了。
在互联网中也有这种需求,就产生了数字签名技术。
我们在非对称加密时已经介绍过了,只有产生非对称加密秘钥对的人才拥有私钥。这个唯一性和你的指纹是不是很像。我们拿非对称加密私钥+签名技术,就可以实现对信息进行数字签名。签上了你的名,就代表是你。别人没有你的私钥,无法签出和你一样的签名的。
数字签名技术,签名和验签是配套的,没有谁只发明枪不发明子弹的。
使用非对称加密的私钥进行数字签名,可以使用非对称加密的公钥进行验签。只需要有签过名的数据包,不需要额外的信息和交互就能验明公钥与私钥是否配对。
注意:说明一下,其实摘要和签名经常搞到一起的,以后说签名就已经带上了摘要。
2.3.3 签名和验签过程示意图
从上图很明显的能看出来,验签过程需要原始数据和公钥即可验证,签名是否是公钥对应的私钥所签。
既然所有的技术都有了,就组合一下,来达到我们的目的。
下图展示了A与B通信过程。A通过B的数字签名实现了对B身份的认证,B未对A进行身份认证;A使用B的公钥加密了对称加密秘钥M1,传递给B;A与B使用M1进行对称加密通信。在这个单向验证的通信过程中,整个过程是安全的。
下面通过展示https这个实际的应用,来更清晰的认识一下,安全通信的整个过程。
我们发现这个例子和上面的基本上一样,不一样的地方就是server向client发送了一个crt的东西。crt就是证书,证书里面放的就有server的公钥,一个签名。
看懂这个实际例子,我们发现我们就看懂了整个安全通信过程。
其实其中还有一个问题,就是身份认证。
我第一次访问www.baidu.com时,我怎么验证和我通信的server是百度呢?
数字签名技术只能验证数字签名与公钥是匹配的。即该信息是公钥对应的私钥发出来的。但是这样的公钥与私钥对,随便就能创建一个,不能说明是百度的。除非百度把他的公钥固定死,且人尽皆知。这样server发来一个证书的时候,判断公钥是不是那个百度固定死的公钥,然后再验签。如果一万个网站要定死一个公钥,显然这种做法是不成立的。
问题总比办法多,是这样子的,习惯了就好。有一个办法,就是创建一个上帝,上帝管理这些麻烦事。
这个上帝有自己的非对称加密的公钥,私钥。大家一看到这个公钥就知道是上帝。
上帝给自己颁发一个上帝证。上帝证上有公钥,摘要,签名(上帝自己给自己签名,叫自签名证书),这样上帝就持证上岗了。
所有想得到别人认证的人,都需要上帝在他的证书上签一个名。签上了上帝名的证书拿给别人看,别人就相信你证书上的内容了。
所以上帝说你是百度,那我相信你就是百度。这就是解决了你到底是不是百度的问题。
所以百度,阿里,腾讯想要证书证明自己身份,就都去找上帝签个名。我们看到上帝签名了,就相信证书上的信息了。
上面就是上帝签过字的百度证书。证书上有证书持有者的信息,国家,省,组织,常用名称等;谁给百度发的这个证;证书的过期时间;
当然证书里面有百度的公钥和一个签名。将来访问百度的client要使用这个公钥来加密对称加密秘钥。这个签名本来应该是上帝的签名的,但是上帝很忙,不可能事事亲为。这个签名是上帝授权的签证官(GlobalSign nv-sa)的签名。
先填一个证书申请表,英文名叫csr(Cerificate Signing Request),把表填好交给签证官等结果就行。表里面需要填持证人基本信息和自己的公钥。
签证官使用自己的私钥对原始证书进行签名,获得带签名的证书。上帝的证书是上帝自己签的。签证过程如下图:
上帝很忙,不可能为每一个证书签名。所以上帝给几个签证官签字,让签证官去给其他人签字。这样证书就是一层一层的签字,形成了证书链。证书链如下图所示:
下图为百度真实的证书链
原理是用数值签名技术来确认身份。固定一个根证书(上帝),大家都相信根证书(上帝),这种信任不断传递,直到被验证人的证书为止。
签证规则是,从root证书签名level2的证书,level2的证书可以继续签名level3的证书,无穷尽也。
验证规则,从被验证书开始逐级往上查找证书,直到根证书。验证根证书是使用根证书自己的公钥进行验签,之后的都是拿上级证书的公钥进行验当前证书的合法性。
以百度为例,拿到百度的证书后,我去找谁给他颁发的证书,发现是GlobalSignG2。接着找谁给GlobalSignG2颁发的证书,发现是GlobalSign root CA。GlobalSign root CA这个是被大家所公认的根证书(上帝)。
我们知道根证书是自签名证书,我们使用根证书(GlobalSign root CA)的公钥去验根证书的签名(指纹),如果合法则往下验证。拿根证书(GlobalSign root CA)的公钥验GlobalSignG2证书的签名,如果合法则往下验证。拿GlobalSignG2证书的公钥验证百度证书的签名,如果合法则说明此证书确实是百度的证书。这样就实现了百度这个身份的认证。
这样就介绍完了安全通信的基本过程和使用的技术。下面实操一下。
-subj "/C=CN/ST=Guangdong/L=Guangzhou/O=xdevops/OU=xdevops/CN=gitlab.xdevops.cn"
进行5.1,5.2和5.3就能产生一个根证书;进行5.1,5.2产生一个csr,把这个csr提供给有根证书的人,进行5.4,就能申请到一个证书了。
csr是证书申请表,crt是证书,key非对称加密的私钥
脚本生成根证书如下:
#!/bin/bash
if [[ $# != 1 ]]
then
echo "usage $0 subject"
echo "usage $0 /C=CN/ST=Guangdong/L=Shenzhen/O=manufacter/OU=model/CN=Yp"
exit 0
fi
# Locate shell script path
SCRIPT_DIR=$(dirname $0)
if [ ${SCRIPT_DIR} != '.' ]
then
cd ${SCRIPT_DIR}
fi
# Generate RSA private key
openssl genrsa -des3 -passout pass:x -out ca.pass.key 2048
# Remove password in the private key
openssl rsa -passin pass:x -in ca.pass.key -out ca.key
rm -f ca.pass.key
# Generate CSR sign request
SUBJ="$1"
openssl req -new -key ca.key -out ca.csr -subj "$SUBJ"
# Generate CRT signed cert
openssl x509 -req -days 7200 -in ca.csr -signkey ca.key -out ca.crt
使用根证书对csr签发证书脚本如下:
#!/bin/bash
#if [[ $# != 2 ]]
#then
# echo "usage $0 ca_path subject"
#echo "usage $0 ../root/ /C=ES/ST=Madrid/L=Alcobendas/O=Jazztel S.A./CN=acs.jazztel.com"
# echo "usage $0 ../root/ ../orange/acs_jazztel_com.csr"
# exit 0
#fi
# Locate shell script path
SCRIPT_DIR=$(dirname $0)
if [ ${SCRIPT_DIR} != '.' ]
then
cd ${SCRIPT_DIR}
fi
CA_PATH=$1
CSR_PATH=$2
CA_PATH="../root/"
CSR_PATH="../ange/com.csr"
CRT_FILE="level2-`date +%Y%m%d%H%M%S`.crt"
# Generate CRT signed cert
openssl x509 -req -days 4015 -in $CSR_PATH -CA "$CA_PATH/ca.crt" -CAkey "$CA_PATH/ca.key" -CAcreateserial -out $CRT_FILE
生成证书申请表csr(证书签名请求,求求你帮我签个名)
#!/bin/bash
if [[ $# != 1 ]]
then
echo "usage $0 subject"
echo "usage $0 /C=CN/ST=Guangdong/L=Shenzhen/O=Yp/OU=Yp/CN=Yp"
# echo "usage $0 ../root/ ../orange/acs_jazztel_com.csr"
exit 0
fi
# Locate shell script path
SCRIPT_DIR=$(dirname $0)
if [ ${SCRIPT_DIR} != '.' ]
then
cd ${SCRIPT_DIR}
fi
KEY_PASS_FILE="cpe-tenbay.pass-`date +%Y%m%d%H%M%S`.key"
KEY_FILE="cpe-tenbay-`date +%Y%m%d%H%M%S`.key"
# Generate RSA private key
openssl genrsa -des3 -passout pass:x -out $KEY_PASS_FILE 2048
# Remove password in the private key
openssl rsa -passin pass:x -in $KEY_PASS_FILE -out $KEY_FILE
rm -f $KEY_PASS_FILE
CSR_FILE="cpe-tenbay-`date +%Y%m%d%H%M%S`.csr"
# Generate CSR sign request
SUBJ="$1"
openssl req -new -key $KEY_FILE -out $CSR_FILE -subj "$SUBJ"
好吧。能看到这里的人不多了。拜拜。