互联网加密及 OpenSSL 介绍和简单使用

一、互联网通信安全简述

1.1、安全问题

随着互联网不断发展,网络安全日益重要,而在互联网上的两台主机间通讯安全成为隐患,其主要面临两大问题 : 身份认证与数据安全

1.2、身份认证

当互联网上两台从未通讯过的主机进行通讯时,比如我们第一次访问支付宝网站,我们如何确信对方主机是真实的,比如我们在浏览器中输入支付宝的地址最终到达的主机是支付宝的主机,而并非别人仿造的假的钓鱼网站?此时面临的问题就是一个 身份认证 问题,即对方要能证明其身份。

1.3、数据安全

假设已经解决了身份认证问题,那么接下来的操作如何保证数据不被窃取?比如在支付宝网站进行转账操作,如何保证密码传输过程中不会被别人窃取;此时面临的就是 数据安全 问题。

二、加密算法

2.1、加密方式分类

目前互联网上的加密算法主要分为三大类 : 对称加密(双向加密)、非对称加密、公钥加密。

2.2、对称加密

对称加密也称作双向加密,即 加密与解密使用同一密码,对明文使用密码加密后,对方可以通过同一密码进行反向解密,加密安全性完全依赖于加密密码。常见的加密算法有 DES(56bits)3DESAES(128bits)BlowfishTwofishIDEARC6CAST5Serpent等等;此种方式加密容易遭受 字典攻击,同时解密方需要得到加密密码,中间可能涉及密码传输泄露问题;此种加密一般都是 将原文分割成固定大小的数据块,对这些块进行加密(ECB,CBC)。

2.3、非对称加密

非对称加密与对称加密相反,其加密解密可使用不同的密码,常见的如 RSAEIGmalDSA 等。

2.3.1、单向加密

在非对称加密中,有一种比较特殊的加密叫做单向加密,单向机密也称消息摘要算法,其主要目的是提取消息特征码,加密后的密文不可逆。常见的单向加密算法有 : MD5SHA1SHA512CRC-32(循环冗余校验码) 等;单向加密有两个重要的特性 : 定长输出、雪崩效应;定长输出可以理解为 无论消息体多大,最终输出加密后结果长度一致,雪崩效应顾名思义,即消息体的微小变化,会导致加密结果的巨大变化。

2.4、公钥加密

公钥加密时会有两个文件,即一个公钥一个私钥;并且公钥与私钥成对出现,其特性是 使用公钥加密的内容必须使用与其匹配的私钥解密,反之亦然。

三、解决方案

3.1、身份认证的解决

由上可知,首先我们面临的第一个问题就是身份认证问题,即 “支付宝要能证明他是支付宝”;纵观以上3中加密算法,比较适合做身份认证的就是 公钥加密即在互联网上从未通讯过的主机想向对方证明自己的身份,只需先生成一对密钥,然后将公钥放在互联网上大家可任意获取,私钥自己保留;需要证明身份时只需用自己的私钥加密一段信息发给对方,对方若能使用其公钥解密,就能证明其身份。简单的例子如下所示,支付宝服务器先将自己的公钥放到互联网上,然后我们需要支付宝服务器证明其身份的时候,支付宝服务器先用自己的私钥加密一段文字,若我们使用互联网上的支付宝公钥能够将其解密,则就能证明此服务器是真实的

hexo_openssl_shenfenrenzheng1

3.2、CA 机构

上面的做法似乎完美的解决了身份认证问题,但并非如此,这中间存在一个巨大漏洞;即 如何保证从互联网上获取的公钥就是对方的,而不是别人恶意放到互联网上的假冒公钥。此时的解决方案就是 大家找一个公认的知名机构,把公钥全部放到这个机构那,然后谁需要谁从那里下载,此时这个机构称之为 CA,CA 为每个使用者颁发一个证书,证书中包含其公钥和CA 的私钥签名,以及一些使用者信息;同时证书具有级联信任关系,即 我们信任了一家 CA 的根证书,那么由其颁发的其他证书将都被信任,类似于一棵树的结构,一旦我们信任了根节点那么以下所有子节点将全部被信任。

hexo_openssl_shenfenrenzheng2

3.3、数据加密的解决

当我们使用公钥加密和 CA 机制解决了身份认证以后,接下来的问题就是数据传输过程中的加密问题;既然是传输数据,那么数据内容肯定需要双向加密才可以被接收方解密读取,但是很大的问题是 双向加密时,解密方需要知道解密密码;而将密码在互联网上传输明显是不明智的,此时出现了另一种解决方案,即 密钥交换算法,专门用于在互联网上传输密钥信息。

3.3.1、Diffie-Hellman 算法

Diffie–Hellman 是著名的密钥交换算法,其基本原理如下:

  • 首先两台计算机互相通讯,并约定选取一个大素数 g
  • 然后两台计算机再协商一个计算数 p
  • 接下来每台计算机随机选定一个随机数,此随机数并不会发给对方(x、y)
  • 通讯时,A 计算机计算 g^x % p 发给 B 计算机
  • 接下来同样 B 计算机计算 g^y % p 发给 A 计算机
  • B 计算机拿到 g^x % p 后再进行 (g^x % p)^y 即最终结果为 g^xy % p
  • 同样 A 计算机拿到 g^y % p 后再进行 (g^y % p)^x 即最终结果为 g^xy % p
  • 此时两台计算机结果将一致,接下来传送的数据便以此结果为密码进行加密即可

此过程中双方都保留了私有的 x、y 随机数,x、y 并未在互联网上传输,所以是安全的,并且由离散数学原理 x、y 被推测的可能性很小,以当前计算机性能基本不可能推测(不要提超级计算机,黑客没那个资源)。

3.3.2、Diffie-Hellman 算法示意图

Diffie-Hellman 算法示意图如下

hexo_openssl_DH

3.4、数据完整性

以上部分已经实现了身份校验以及数据加密操作,接下来我们需要保证数据的完整性,对于完整性最好的应用就是采用单向加密即消息摘要算法,提取数据的特征码;简单地说就是每发送一段数据,就对发送的数据做一次数据特征提取,然后将特征码一并发送,接收方接收到数据并解密后可对其使用同样的算法进行特征码提取比对,如果计算结果不一致则证明数据被篡改,直接丢弃即可。

hexo_openssl_datawanzheng

四、OpenSSL 使用

4.1、OpenSSL 简介

OpenSSL 是一组加密套件,其提供了功能强大的加密解密功能,以及证书相关的操作工具,OpenSSL 分为三大部分 : libcrypto 通用功能的加密库、libssl 用于实现TLS/SSL的功能 和 openssl 多功能命令工具;而一般 OpenSSL 使用指的就是多功能命令行工具的使用。

OpenSSL 有许多子命令,可通过 openssl ? 查看其支持子命令和加密算法等信息

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
27
28
29
30
31
32
33
Standard commands
asn1parse ca ciphers cms
crl crl2pkcs7 dgst dh
dhparam dsa dsaparam ec
ecparam enc engine errstr
gendh gendsa genpkey genrsa
nseq ocsp passwd pkcs12
pkcs7 pkcs8 pkey pkeyparam
pkeyutl prime rand req
rsa rsautl s_client s_server
s_time sess_id smime speed
spkac srp ts verify
version x509

Message Digest commands (see the `dgst' command for more details)
md4 md5 rmd160 sha
sha1

Cipher commands (see the `enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb
aes-256-cbc aes-256-ecb base64 bf
bf-cbc bf-cfb bf-ecb bf-ofb
camellia-128-cbc camellia-128-ecb camellia-192-cbc camellia-192-ecb
camellia-256-cbc camellia-256-ecb cast cast-cbc
cast5-cbc cast5-cfb cast5-ecb cast5-ofb
des des-cbc des-cfb des-ecb
des-ede des-ede-cbc des-ede-cfb des-ede-ofb
des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb
des-ofb des3 desx rc2
rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfb
rc2-ecb rc2-ofb rc4 rc4-40
seed seed-cbc seed-cfb seed-ecb
seed-ofb

4.2、OpenSSL 实现加解密

4.2.1、加密操作

OpenSSL 使用子命令 enc 实现加密,命令格式如下

1
openssl enc -算法 -salt -a -salt -in 输入文件 -out 输出文件 -k passwd

如下为加密一个文件示例

1
openssl enc -aes-256-ecb  -a -salt -in /etc/profile -out ~/test -k test123

-a 选项用于将加密后内容以 base64 格式输出,加密后内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
U2FsdGVkX1/tVWQ7cGR5rTLU9Phnx7csis12ukuGpZTWx7sDiJ8Qdb4Jn8hvShnW
7gPouyOwJlKufoDHXT2hqOnw/i8Rf5QisLc+EOXgUWDFun3AqHte6YmNbelDFchu
hDsph4Vq7TNBmZ/C1LHSCnMoA39qHBWxyrIstpOWs5TWkdPjDgEVZkIXNiWIwoRF
CDVv7AuZXO9qF3sMb4fLWPF9cM7FkbvGkkhzBJZ0dAdq8DetKaZyjOX4UfeWPSav
U61t9s7hlmjEPmXpUSSfnO8/7u0B/EEnujpkwyNZXbQBcQ9QFDh7x1vdzQIAuMRw
0SLsVm1OSOifvMOpOAJCmvhExrKsznWgQlQabLOWsr29yrs0YBuwSl6oUSf8Qx1S
3z/GC7l13zzmHwXJTgPRe0WzdLYsy6GMj2/0DveLvcXT/cXGid69tzIf4JaczIEX
zSS4N12C3CFS/60poXZmiwoNsC3n6ESBf3dZum6LKA9sNPdxveb/RTZ4KYl/iw9S
NgAqNGa9Yp1xdyl2NBaruvDxVAGbwC+rGn9UjbIYbEdT7ZjKPjJ6BP8yzwv6jnOU
3E58UVIuIEVWJY3kF77+Vk99JuQepFRGX9sHYdafQR7AISiS88eipn6qkMMDmrkT
kwZtebWyhvmWTZABOa7tckzzYxJ/Ke1jkBudasUJr9RUEiNNmSASdRr0dlZvM/tS
COuPeNo8ZU7ad/yd/OpvPKShn9Hh9oXCKSB4vl/DQVefVXWAaTp49FFAGFrQThiQ
rAwHwrJ/N2ab0Do0iArctNTqz5u7MtEHwVtFsV45YJfAGQRwTg06Y6qKjhgWmBjX
EGNGbP7c0A1SiI/g8maKl3ciTwWPWXCcpf14MFcYBvjpA7EVYSYTh7hSxzUtY0gk
l3EUVrqnY0M8u+0LBgAcrA==

4.2.2、解密操作

解密操作与加密基本相同,只不过需要加上 -d 选项,代表解密,命令格式如下

1
openssl enc -算法 -salt -d -a -in 输入文件 -out 输出文件 -k passwd

如下为解密一个文件的示例

1
openssl enc -aes-256-ecb -salt -d -a -in test -out test1 -k test123

解密后文件即为原来的 /etc/profile 文件内容

4.3、OpenSSL 创建 CA

关于 CA 证书本文并未做过多解释,限于篇幅,完全解释完太多,以下为一篇写的比较好的文章 点这里;下面主要介绍 OpenSSL 工具建立私有 CA。

4.3.1、OpenSSL CA 相关配置

默认的 Ubuntu 下 OpenSSL 的配置文件位于 /etc/ssl/openssl.cnf,CentOS 位于 /etc/pki/tls/openssl.cnf,我们只需要关注如下部分,关于具体配置含义 Google 之。

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
####################################################################
[ ca ]
default_ca = CA_default # The default ca section

####################################################################
[ CA_default ]

dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.

certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file

x509_extensions = usr_cert # The extentions to add to the cert

# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options

# Extension copying option: use with caution.
# copy_extensions = copy

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext

default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match

# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

4.3.2、生成密钥对

由配置文件可知,OpenSSL 默认的工作目录在 ./demoCA 下,所以需要先创建 CA 所需相关目录,执行 mkdir -p demoCA/{private,certs,crl,newcerts},目录结构如下

hexo_openssl_dirtree

然后生成一个私钥(公钥其实是从私钥中提取的,所以创建私钥就可以从中提取出公钥)

1
2
3
4
# 使用 () 开启子 shell 执行,同时设置掩码
(umask 077; openssl genrsa -out demoCA/private/cakey.pem 2048)
# 如果想查看公钥可执行以下命令(非必须)
openssl rsa -in demoCA/private/cakey.pem -pubout

4.3.3、生成自签证书

作为根 CA,可以生成一个自签名的证书,来标明自己的身份,签名方法如下

1
openssl req -new -x509 -key demoCA/private/cakey.pem -days 3655 -out demoCA/cacert.pem

然后输入相关信息,注意不要乱输入,其中 Common Name 一般为使用者域名,这里暂时填写的是 IP,截图如下

hexo_openssl_createcapb

最后要创建用于签名证书的相关文件,执行 touch demoCA/{index.txt,serial,crlnumber} 创建所需文件,执行 echo "01" > demoCA/serial 初始化序列号,最终文件目录结构如下

hexo_openssl_createcafiledirtree

4.4、OpneSSL 申请证书

同样,先生成一对密钥

1
2
3
4
5
6
# 创建目录
mkdir mycrt
# 生成公钥 扩展名随便取
openssl genrsa -out mritd.key 2048
# 提取公钥
openssl rsa -in mritd.key -pubout > mritd.public.key

接下来要申请一个证书签署请求,信息要保证与 CA 创建时一致(具体可调整 openssl.cnf 配置文件),密码直接回车默认为空密码

1
openssl req -new -key mritd.key -out mritd.csr

截图如下

hexo_openssl_createprivatekey

最后使用 CA 进行签署即可(注意,要回到 demoCA 上一级目录),提示是否确认全部 y 即可

1
openssl ca -in mycrt/mritd.csr -out mycrt/mritd.crt -days 3655

截图如下

hexo_openssl_signedcrt

最终生成的 mritd.crt 即为可用的证书


互联网加密及 OpenSSL 介绍和简单使用
https://mritd.com/2016/07/02/encryption-and-introduction-to-openssl/
作者
Kovacs
发布于
2016年7月2日
许可协议