What is PKI and SSL

大学毕业之后,笔者就再也没有怎么学习过]。因为工作需要,笔者最近正好要好好地学习一下Website Security方面的知识。我决定一边学一边记录在我自己的blog里,一方面可以帮我梳理学到的知识,以防以后忘记了;另一方面如果有朋友看到本文可以得到些许的启发那就更好了。

今天第一篇,我想先讲讲PKI和SSL的大概概念以及他们的关系。

PKI 全称是Public Key Infrastructure,中文名巨拗口,叫公开密钥基础建设PKI真要说起来非常复杂,简单的来说就是通过PKI定义了如何在点对点(可以是User 对User,User 对Server 等)的信息交换中,接收方如何确认发件人的身份以及双发送信息的安全。

SSL全称是Secure Socket Layer,现在进化成TLSTransport Layer Security)是一种基于PKI系统的安全协议,目的是为了保障互联网的通信安全。

由于目前人们对于网络的依赖程度已经到了疯狂的地步,网络安全问题已经是这个年代最为重要的一个议题。用户个人的数据保护意识是一个可以提高的部分,在用户看不到的地方,PKI/SSL起着至关重要的作用。

Concept说完,真的有点枯燥,我们来点好玩的东西。我们来聊聊两种常用的加密方式。

Symmetric

Symmetric中文叫做对称式加密,具体的来说就是用户A和用户B协商好我们用共同的一把钥匙来加密和打开我们交换的信息。

二战时期德国人制作的恩尼格玛密码机就可以理解成Symmetric加密的一种应用了。光说不练假把式,让我们先来做个小测试,我们首先生成一个Key文件用来加密和解密.

openssl rand -base64 128 > sym.key

> 前面的部分是生成key的命令,后面的部分说的是把前面生成的key保存在本地一个叫sym.key的文件里面。上文的命令就是实际生成一个base64,128位的密码。

接下来我们可以尝试加密一个叫test的文档

1
2
3
4
5
6
7
8
$ cat test.txt
This is a testing file
$ openssl enc -aes-256-cbc -salt -in test.txt -out test.txt.enc -k sym.key
$ cat test.txt.enc
Salted__C?c????~L?N??20??*$?n??$k?џ????W?s
$ openssl enc -aes-256-cbc -d -in test.txt.enc -out test.txt.dec -k sym.key
$ cat test.txt.dec
This is a testing file

可以看到这里我用的AES 256 cbc的加密模式把文件内容进行加密。之前的sym.key文件同时用来加密和解密,因此这就是所谓的对称式加密了。这个加密方法的好处在于节省时间,因此用来加密大块信息的时候,symmetric是一个很好的方法。

然而有利就有弊,Symmetric有它不可逾越的制约性。首先就是加密强度跟Asymmetric比起来差了一大截;其次就是如何确保把钥匙交给你想给的人(如下图)是个大问题。

Alice如何可以确保正在跟她聊天的人就是Bob呢?即使她确定是bob了,怎样把这个key文件给他而不被截获呢?

Asymmetric

Asymmetric加密就应运而生了。对比起Symmetric用同一个密匙加密和解密,Asymmetric用的是一对密匙:公钥和私钥。公钥可以公开给任何人持有,私钥自己保留。发信者可以用对方的公钥加密要发的信息之后,只有持有私钥的接收方才能解密这个信息,即使是用来加密的公钥也不能解密已经加密过的信息了。

基于公开密钥的特性,该方法还提供数字签名的功能,使得电子签名可以得到纸本签名的效果。

我们也用一些例子来测试一下其,签名的过程。

加密和解密
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
# 生成一个名字叫private的私钥
$ openssl genrsa -out private.key 2048

# 根据这个私钥生成一个叫public的公钥
$ openssl rsa -in private.key -pubout > public.pem

# 我们已经预先创建了一个文档test.txt
$ more test.txt
This is a testing File for Encryption and Decryption

# 使用公钥加密该文件,加密后的文件名为cipher.txt
$ openssl rsautl -encrypt -in test.txt -pubin -inkey public.key -out cipher.txt

# 可以看到内容加密后的文件内容
$ more cipher.txt
§¾L/Ûú±m¢/óÃG {­L½x▲Ì ¼¤2uÑ!Ãñ♠ç♂÷♠↕¡└¾÷¾óÑ­!·#▀·u­ü!èØP►w¸áN½ñ═9┌ó¹kwð8ô\¾┌µ╗v┤Oy;%'Ï▼
|Ëp¥♣Ê♀┤xÄ?Ùà qr¸"┴Å¿■2ßÖµ╬,↨ÀdÁ█ ÚéT<½/═▼ðt♫→cO2F@s>³WQ­p³¾îan▲?/ê░Å¿♦¶☺umc↨‼↔´░╚⌂Y©2E¬♥¥òýu¥Þ>¨b¬Xê­ÎorÜnµ╚­Ñ#ü3ä¸f╣║]┐

# 用私钥(Private.key)来解码这个加密过的文件就可以得知内容
$ openssl rsautl -decrypt -in cipher.txt -inkey private.key
This is a testing File for Encryption and Decryption

# 如果我们尝试使用公钥(public.key)来解码会报错
$ openssl rsautl -decrypt -in cipher64.txt -inkey public.key
unable to load Private Key
1548:error:0906D06C:PEM routines:PEM_read_bio:no start line:crypto\pem\pem_lib.c:691:Expecting: ANY PRIVATE KEY

接下来我们看看怎么验证电子签名。

签名与验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 首先用私钥来签名一个文件
$ openssl rsautl -sign -inkey private.key -out test.txt.sig -in test.txt

# 可以看到
$ more test.txt.sig
4╔$WbZÙÀ̺¦òu­&B┤♫ð²▀(¤3¼‗╦
XJ▲r¾N‗ƒ¦┴ o@╬Íãû,):Ë×.£▼♂ñZc→®♫\µ
‼|·§ËÅ+∟IÑv5+BÞà¹↨þ%A{],Ú◄W↓uR/▀@X]┴æ¸ÐBe¾äÈØù,¸³╚MÊ]╗TVî[▬╩>Ä÷À:­%]r╔ƒHø2N→ëı_└iÐÄ=³┤┬←}Æ9dKû
¼☻×ø♥♀\Û<↓8└¢☺IR▒ÿYüÖ♫5ì░Ô:)f8♀óÅt█└╣e▀╩■¨J¡↑§þ»{ÍÓ#╚áOûm¨Â¼3¯⌂áÜKKı¾Éü,ô◄,1♂┼9▬Å┘╣G!]À↨↓ıì┐6´Þ

# 最后用公钥来验证
$ openssl rsautl -verify -inkey public.key -in test.txt.sig -pubin
This is a testing File for Encryption and Decryption

# rsautl这个方法,签名的同时明显把源文件也囊括进去,我们来试试另外一个方法