加解密,加签、验签也就这肥事

444 阅读34分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情

前言: 在这里插入图片描述

ps:上图有一处错误,右下角有一条线是N,指向的是不读取内容

上图省略了CA认证过程,直接提取到了密钥对,Base64的过程已省略(关于Base64的底层原理,可参考标题3)。全文1.6w字,如果想全部了解,可能需要花一点时间,相信大家看完一定会有所收获。

1.非对称加密

1.1简介

  • 非对称加密技术,需要两个秘钥,公钥和私钥。公钥和私钥成对出现。
  • 优点:安全性更高,公钥是公开的,秘钥是自己保存的,不需要将私钥给别人。
  • 缺点:加密和解密花费时间长、速度慢,只适合对少量数据进行加密。
  • 常见算法有:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)等。

1.2.为何只能用公钥进行加密、解签,私钥解密、加签

加签的目的:验证信息的发送方是否正确,信息是否被其他人篡改。

  • 之所以用发送方的私钥加签,是因为,即便信息被黑客拦截,黑客修改了信息,但是加签需要用发送方的私钥,黑客没有发送方的私钥,所以也无法生成正确的签名,接收方验签就不用通过。

  • 反之如果用接收方的公钥加签,如果信息被黑客拦截,黑客修改了信息,因为接收方的公钥是公开的,黑客就可以重新生成新的签名,替换原有的签名,发送出去,接收方接收到信息,拿自己的公钥校验是通过的,所以接收方无法辨别信息是真正的发送方还是黑客发送过来的,这样的加签不能辨别信息是否被篡改过

加密的目的:保证信息的隐私,不被别人看到,只能让接收方看到正确的信息。

  • 之所以用接收方的公钥加密,是因为,如果信息被黑客拦截,需要用接收方的私钥来解密,黑客无法获取接收方的私钥,即便拦截了信息(情报),黑客也无法看到明文,只能看天书?了。

  • 反之,如果用发送方的私钥加密,如果信息被黑客拦截,因为发送方的公钥是公开的,黑客就可以用发送方的公钥解密密文获得明文,这样的加密所有的人都可以看到明文,不能保证信息的隐私。

1.3.公钥与私钥原理

ps:1.3章节内容摘录自互联网,觉得写得非常好,为方便大家理解,便作为了本篇文章1.3章节内容。 公钥与私钥原理原文链接:www.cnblogs.com/ghc666/p/10… 1)鲍勃有两把钥匙,一把是公钥,另一把是私钥

在这里插入图片描述

2)鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。 在这里插入图片描述

3)苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。 在这里插入图片描述

4)鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。 在这里插入图片描述

5)鲍勃给苏珊回信,决定采用"数字签名"。他写完后先用Hash函数,生成信件的摘要(digest)。

在这里插入图片描述

6)然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature)。

在这里插入图片描述

7)鲍勃将这个签名,附在信件下面,一起发给苏珊。 在这里插入图片描述

8)苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。

在这里插入图片描述

9)苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

在这里插入图片描述

10)复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成"数字签名",写信给苏珊,让苏珊用假的鲍勃公钥进行解密。 在这里插入图片描述

11)后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate)。 在这里插入图片描述

12)鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。

在这里插入图片描述

13)苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明"数字签名"是否真的是鲍勃签的。 在这里插入图片描述

1.4 CA证书

1.4.1简介

  • CA中心,又称为数字证书认证中心,作为电子商务交易中受信任的第三方,专门解决公钥体系中公钥的合法性问题。CA中心为每个使用公开密钥的用户发放一个数字证书,数字证书的作用是证明证书中列出的用户名称与证书中列出的公开密钥相对应。CA中心的数字签名使得攻击者不能伪造和篡改数字证书。
  • Ukey厂商,Ukey又称USBKey,是数字证书的硬件载体。目前国内的UKey厂商有大明五洲、海泰、恒宝、中钞、华大等。
  • 业务系统需要在CA登记注册获取根证书,然后对根证书签发给客户的数字证书做校验和解密。

1.4.2CA证书的属性

1、证书DN,X.509证书使用DN(Distinct Name)来标识一个实体,其功能类似于我们平常使用的ID,可以在制证过程中和证书属性中查看,如下图所示 2、证书SN(Serial Number),证书序列号是证书的唯一标识。和DN的区别是,当发生换证、补发情况时,DN是相同的,而SN是不同的。 3、参考号和授权码,这两个字段用在证书下载过程中。 4、证书状态有:未下载、激活、冻结和注销。 5、颁发者,是证书的签发证书DN,在证书验证过程中需要验证该属性

1.4.3CA数字签名过程

在这里插入图片描述

如上图所示,它分为两个过程,第一个过程是签发证书,它可以对数据进行签名(不仅是传输的数据、公钥及其包含的一些相关信息也可以看作是一段数据),第二个过程是验证证书如下。 签发证书的过程

  1. 撰写证书元数据:包括 签发人(Issuer)、地址、签发时间、有效期 等,还包括证书持有者(Owner)基本信息,比如 DN(DNS Name,即证书生效的域名)、 Owner 公钥 等信息
  2. 使用通用的 Hash 算法(如SHA-256)对证书元数据计算生成 数字摘要
  3. 使用 Issuer 的私钥对该数字摘要进行加密,生成一个加密的数字摘要,也就是Issuer的 数字签名
  4. 将数字签名附加到数字证书上,变成一个 签过名的数字证书
  5. 将签过名的数字证书与 Issuer 的公钥,一同发给证书使用者(注意,将公钥主动发给使用者是一个形象的说法,只是为了表达使用者最终获取到了 Issuer 的公钥)

验证证书的过程

  1. 证书使用者获通过某种途径(如浏览器访问)获取到该数字证书,解压后分别获得 证书元数据 和 数字签名
  2. 使用同样的Hash算法计算证书元数据的 数字摘要
  3. 使用 Issuer 的公钥 对数字签名进行解密,得到 解密后的数字摘要
  4. 对比 2 和 3 两个步骤得到的数字摘要值,如果相同,则说明这个数字证书确实是被 Issuer 验证过合法证书,证书中的信息(最主要的是 Owner 的公钥)是可信的。

1.4.4证书链

  • 全世界的顶级 CA(Root CA) 就那么几个,每天都有很多人要向它申请证书,它也忙不过来啊,怎么办呢?它可以选择继续往下授权,向下一级授权,这样我们就只要找一级/二级/三级 CA 申请证书即可。
  • 比如一级 CA 让 Root CA 来签名认证,二级 CA 让一级 CA 来签名认证,Root CA 没有人给他签名认证,只能自己证明自己了,这个证书就叫「自签名证书」或者「根证书」,我们必须信任它,不然证书信任链是走不下去的。

如下举例来看我们的根、一级、二级等CA,如下是Chrome浏览器,打开的是百度的网址,前面有一个小锁,我们点击然后再点击connection is secure,如下: 在这里插入图片描述

然后再点击certificate is valid

在这里插入图片描述

点击后可以看到如下内容:

在这里插入图片描述

该证书的层次关系为: GlobalSign Root CA -> GlobalSign Organization Validation CA -> baidu.com 对其解释:

  • end-user:即 baidu.com,该证书包含百度的公钥,访问者就是使用该公钥将数据加密后再传输给百度,即在 HTTPS 中使用的证书
  • intermediates:即上文提到的顶级CA向下授权的中间CA,用来认证公钥持有者身份的证书,负责确认 HTTPS 使用的 end-user 证书确实是来源于百度。这类 intermediates 证书可以有很多级。
  • root:可以理解为 顶级的CA,负责认证 intermediates 身份的合法性。 在这里插入图片描述 该证书链的认证过程可以简要总结为如下:
  1. 为了获取 end-user 的公钥,需要获取 end-user 的证书,因为公钥就保存在该证书中
  2. 为了证明获取到的 end-user 证书是可信的,就要看该证书是否被 intermediate 权威机构认证,等价于是否有权威机构的数字签名
  3. 有了权威机构的数字签名,而权威机构就是可信的吗?需要继续往上验证,即查看是否存在上一级权威认证机构的数字签名
  4. 信任链条的最终是Root CA,他采用自签名,对他的签名只能无条件的信任

2.对称加密

2.1.简介

在这里插入图片描述

图片来自百度百科

  • 采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

  • 优点:

    • 对称加密算法的优点是算法公开、计算量小、加密速度快、加密效率高。
  • 缺点:

    • 对称加密算法的缺点是在数据传送前,发送方和接收方必须商定好秘钥,然后使双方都能保存好秘钥。其次如果一方的秘钥被泄露,那么加密信息也就不安全了。另外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的独一秘钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理成为双方的负担。
  • 常见的算法有:DES、3DES、Blowfish、IDEA、RC4、RC5、RC6和AES等。

  • 它的缺点是非常明显的,那么对称加密有其用武之地吗,答案肯定是有的,在传输大量数据的时候,它与非对称加密配合着使用(即对称+非对称)

2.2.对称+非对称加密进行传输大量数据

  1. 我们可以先用对称加密方式对需要传输的数据(优点:加密速度快、加密效率高)进行加密得到加密数据;
  2. 之后再把对称加密方式中用到的密钥(也就是步骤1中用到的密钥)用非对称加密方式进行加密(优点:安全性更高)得到加密后的密钥;
  3. 组装好步骤1得到的加密数据和步骤2得到的加密后的密钥,然后发送给对方。

这样二者想结合,就具备了加密速度快、加密效率高,安全性更高的特点,具体流程如下: 在这里插入图片描述 ps:上图有一处错误,右下角有一条线是N,指向的是不读取内容


3.Base64编码底层原理

在开发中,我们经常会遇到使用Base64的场景,这里本人详细阐述一下Base64的底层原理。

3.1.作用

  • 按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.) 传输8Bit字节代码的编码方式之一。
  • Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。不是加密算法,只是无法直接看到明文。可以通过打乱Base64编码来达到类似加密的效果。
  • Base64就是一种基于64个可打印字符来表示二进制数据的方法,把一些不可打印的字符转换成全部都是可打印的字符。

ps:关于ASCII编码(含扩展ASCII)中,打印字符和不可打印字符:blog.csdn.net/MrYushiwen/…

3.2.Base64编码转换表(64个可打印字符)

总共64个可打印字符,从0开始到63结束。 在这里插入图片描述

3.3.Base64举例说明全过程

3.3.1.规则

关于这个编码的规则:

  1. 把3个字节变成4个字节,6位为一组,高位补两个0,组成一个字节,这样十进制中正好从0到63
  2. 每76个字符加一个换行符。
  3. 最后的结束符也要处理。 Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
ps:为什么每76个字符要加一个换行符,如下:
RFC2045中有规定:
The encoded output stream must be represented in lines of no more than 76 characters each.
Base64一行不能超过76字符,超过则添加回车换行符。
“回车换行符(\r\n)”是在Windows才有,而Linux只有换行(\n),Mac只有回车(\r)。

3.3.2.举例一(末尾没有=号)

把UTF-8编码的abc进行base64编码其具体过程如下:

  1. UTF-8编码的abc其底层用二进制表示为01100001 01100010 01100011
  2. 拆分,每六位一组:011000 010110 001001 100011
  3. 高位补两个0:00011000,00010110,00001001 , 00100011
  4. 查找base64编码转换表,00011000,00010110,00001001 , 00100011十进制为:24,22,9,33,对于的字符为:YWJj

3.3.3.举例二(末尾有=号)

在1中的规则,第一条对于这个有稍微的变化,因为这个末尾差分6个为一组时,最后只有4个,怎么办呢,先低位补0,补成6位,然后在高位补两个0,组成一个字节,这样十进制中正好从0到63

把UTF-8编码的ab进行base64编码其具体过程如下:

  1. UTF-8编码的ab其底层用二进制表示为01100001 01100010
  2. 拆分,每六位一组,末尾只有4位,先低位补0,补成6位:011000 010110 001000
  3. 高位补两个0:00011000,00010110,00001000
  4. 查找base64编码转换表,00011000,00010110,00001000 十进制为:24,22,8对于的字符为:YWI
  5. 在举例1中字节数量应该是3的倍数,如果这个条件不能满足的话,具体的解决办法是这样的:剩余的字节根据编码规则继续单独转过程如上述所述,最后再用=号补满4个字节。这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。因为一个原字节至少会变成两个目标字节,所以余数任何情况下都只可能是0,1,2这三个数中的一个。如果余数是0的话,就表示原文字节数正好是3的倍数(最理想的情况)。如果是1的话,转成2个Base64编码字符,为了让Base64编码是4的倍数,就要补2个等号;同理,如果是2的话,就要补1个等号。
  6. 补一个=号,最后结果为:YWI=

3.4.关于URL的改进Base64编码

  • 标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。
  • 为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,即把 二.base64编码转换表(64个可打印字符)中的62和63对应的字符改成了-_ ;这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

4.关于OpenSSL、Keytool生成密钥对

4.1简介:

OpenSSL:

  • OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。

  • 即OpenSSL是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。

keytool :

  • JDK自带的Keytool,它是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务。在JDK 1.4以后的版本中都包含了这一工具,它的位置为“%JAVA_HOME%\bin\keytool.exe”。

为节省时间本人只讲解了如何使用了keytool去生成密钥对,即4.3章节的内容;关于使用OpenSSL软件库包生成密钥对参考了网上的该篇博客: 即4.2章节中以下内容来自该篇博文:www.cnblogs.com/linjiqin/p/…

4.2OpenSSL生成密私钥、公钥(非CA认证的公钥)过程(PKCS#8编码):

下面将介绍在Linux系统下生成公私钥,当然也可以使用其他开源平台提供的已编辑好的工具。 我们主要了解其过程,帮助我们知道公私钥是怎么来的。 ps:4.2章节中以下内容来自该篇博文:www.cnblogs.com/linjiqin/p/… 当前使用的是Linux系统,已经安装OpenSSL软件包。 如下演示用OpenSSL软件包生成RSA算法的密钥对。 1、执行命令openssl version -a 验证机器上已经安装openssl $ openssl version -a 在这里插入图片描述 2、生成私钥 这条命令让openssl随机生成一份私钥,加密长度是1024位。加密长度是指理论上最大允许”被加密的信息“长度的限制,也就是明文的长度限制。随着这个参数的增大(比方说2048),允许的明文长度也会增加,但同时也会造成计算复杂度的极速增长。一般推荐的长度就是2048位。 $ openssl genrsa -out rsa_private_key.pem 2048 运行结果: 在这里插入图片描述 生成私钥文件:C:\Users\PC\rsa_private_key.pem,内容都是标准的ASCII字符,开头一行和结尾一行有明显的标记,真正的私钥数据是中间的不规则字符。

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAyF3lqF456UvWSyvj5iP5oS4hIprE1fUqR0hHXMHN48f/4ycj
tAml3MSHHeE0j3cnutI5xh5WlZAKI1GLZwcZeg0WNDFiRP6pAdz32w==
-----END RSA PRIVATE KEY-----

3、根据私钥生成公钥:C:\Users\PC\rsa_public_key.pem $ openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 运行结果: 在这里插入图片描述 公钥内容:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyF3lqF456UvWSyvj5iP5
grP5WGPmTggfh6vo2NLdvAngk62UgAALdvokmM4xFs/qj8bDBQ8R2Wqvl3JsX/rd
-----END PUBLIC KEY----

注意:此时的私钥还不能直接被使用,需要进行PKCS#8编码: 4、PKCS#8编码:指明输入私钥文件为rsa_private_key.pem,输出私钥文件为pkcs8_rsa_private_key.pem,不采用任何二次加密(-nocrypt) $ openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt C:\Users\PC\可以看到pkcs8_rsa_private_key.pem文件。 至此:可用的密钥对已经生成好了,私钥使用pkcs8_rsa_private_key.pem,公钥采用rsa_public_key.pem

4.3JDK自带的Keytool生成数字证书/.cer/.p12文件(PKCS#12)

4.3.1生成密钥

秘钥库是存储一个或多个密钥条目的文件,每个密钥条目应该以一个别名标识,它包含密钥和证书相关信息。

  • 如果使用"keytool -genkeypair"命令生成密钥条目,则会生成一个密钥对(公钥和相关私钥)并将公钥包装到X.509 v3自签名证书中,该证书存储为单个元素证书链,此证书链和私钥存储在以别名标识的密钥库条目中,条目类型为PrivateKeyEntry。
  • 如果使用"keytool -genseckey"命令生成密钥条目,则会生成一个密钥并将其存储在以别名标识的密钥库条目中,条目类型为SecretKeyEntry。

下面讲解使用RSA算法,PKCS#12编码生成数字证书,使用"keytool -genkeypair"命令生成密钥条目:

  1. cd进入JDK的bin目录下: 在这里插入图片描述
  2. 输入如下命令:

keytool -genkeypair -alias serverkey -keyalg RSA -keysize 2048 -validity 3650 -keystore D:\demo\p12test.keystore 参数解释:

  • genkeypair:生成一对非对称密钥并将公钥包装到X.509 v3自签名证书中;
  • alias 实体别名(包括证书私钥)
  • dname 证书个人信息 keyalg 采用公钥算法,默认是DSA,这里采用RSA keysize 密钥长度(DSA算法对应的默认算法是sha1withDSA,不支持2048长度,此时需指定RSA)
  • validity 有效期
  • keystore 指定keystore文件储存位置

执行后会要求我们输入一些信息,如下: 在这里插入图片描述注意点:

  • 密钥库的密码至少必须6个字符,可以是纯数字或者字母或者数字和字母的组合等
  • 名字与姓氏应该是输入域名,而不是我们的个人姓名,其他的可以不填
  • 如果创建默认类型(JKS)的密钥库,则可附加"-keypass"参数指定条目的密钥口令,如果没有指定则会在最后一步提示"输入该条目的密钥口令,如果与密钥库口令相同按回车",一般设为与密钥库口令相同。如果创建PKCS12类型的密钥库,则会忽略条目的密钥口令相关参数,因为PKCS12不支持设置密钥库条目密码,默认它与密钥库密码一致。

执行完上述命令后,在操作系统的指定目录下生成了一个"p12test.keystore"的文件。 在这里插入图片描述

4.3.2查看密钥

输入如下命令: keytool -list -v -keystore D:\demo\p12test.keystore 在这里插入图片描述 最后一行提示信息,我们可以执行一下,输入完成后经过转过的key就会生成,原来的key自动会有一个old的后缀,当然不转换直接使用老的key也可以。

4.3.3导出密钥

将密钥库p12test.keystore中别名为serverkey条目的相关信息以及公钥导出到一个数字证书文件p12test.cer中,cmd命令如下: keytool -exportcert -keystore D:\demo\p12test.keystore -file D:\demo\p12test.cer -alias serverkey 参数解释:

  • export 表示证书导出操作
  • keystore 指定秘钥库文件
  • file 指定导出文件路径
  • alias 密钥库中条目的别名

执行完成后生成如下文文件: 在这里插入图片描述 ps:该p12test.cer证书文件不包含私钥。

4.3.4在终端打印数字证书

Keytool -printcert -file D:\demo\p12test.cer 打印内容如下: 在这里插入图片描述 可以看到该数字证书中便只有对应的某个条目的相关信息了(对比4.3.2下的截图)。

4.3.5将.cer格式的证书转换为p12证书

keytool -importkeystore -srckeystore D:\demo\p12test.keystore -destkeystore D:\demo\p12test.p12 -srcalias serverkey -destalias serverkey -srcstoretype jks -deststoretype pkcs12 -noprompt -destkeypass ysw123 在这里插入图片描述 生成如下文件: 在这里插入图片描述 当然p12证书也可以转回cer格式的证书,这里不在继续深入说明,我们只需要弄清楚它们之间的关系就行,想深入了解的同学可以自行查询资料。 p12证书提取密钥流程如下: 在这里插入图片描述

4.4关于ANS.1编码规则

4.4.1ANS.1简介

openssl的数据编码规则是基于ans.1。 百度百科是这样解释的:ASN.1抽象语法标记(Abstract Syntax Notation One) ASN.1是一种 ISO/ITU-T 标准,描述了一种对数据进行表示、编码、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构,而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序。它有两部分:

  1. 数据描述语言标准:语言标准允许用户自定义的基本数据类型,并可以通过简单的数据类型组成更复杂的数据类型。 对于普通数据类型,我们将数据直接转化成数据流进行传输即可;对于复杂数据格式,需要引入一个数字对象的概念,通过将复杂数据结构转化成数据对象。
  2. 数据编码规则:这些编码方法规定了将数字对象转换成应用程序能够处理、保存、传输的二进制形式的一组规则。 也就是编码解码规则,有如下: 基本编码规则(BER) -X.209 、规范编码规则(CER)、识别名编码规则(DER)、压缩编码规则(PER)和 XML编码规则(XER)。

所以,ASN.1标准就是规定了把数据转化成数据对象,又规定数据对象编码为二进制流的方法。 openssl使用的是asn.1的DER编码规则(识别名编码规则),保证每个asn.1对象使用DER编码获得的二进制编码是唯一的。 openssl使用pem作为基本的文件编码格式,pem和der的关系如下图所示,其中几种加密环节是可选的: 在这里插入图片描述 可以看出openssl的pem编码实际上就是在DER编码规则(识别名编码规则)的基础上进行了Base64编码,然后追加了头部信息。 我们也可以使用openssl的相关指令进行DER与pem之间进行转换。

4.4.2ANS.1的应用

  • 在任何需要以数字方式发送信息的地方,ASN.1 都可以发送各种形式的信息(声频、视频、数据等等)。ASN.1 和特定的 ASN.1 编码规则推进了结构化数据的传输,尤其是网络中应用程序之间的结构化数据传输,它以一种独立于计算机架构和语言的方式来描述数据结构。 OSI 协议套中的应用层协议使用了 ASN.1 来描述它们所传输的 PDU,这些协议包括:用于传输电子邮件的 X.400、用于目录服务的 X.500、用于 VoIP 的 H.323 和 SNMP。它的应用还可以扩展到通用移动通信系统(UMTS)中的接入和非接入层。
  • ASN.1的第一部分---数据描述语言标准,这个标准定义了一些基本的数据类型,如果我们使用到复杂的数据结构,asn.1还允许通过简单数据类型组成复杂的数据类型(x.509)。 Java官方关于x.509的实现如下,大家感兴趣可以自己点进源码看一下,这里不深入讨论。

4.5证书相关知识

4.5.1文件编码

  • PEM

    • PEM (Privacy Enhancement Message),定义见 RFC1421。是一种基于 base64 的编码格式,常见于 linux/unix 下的证书编码
    • 结构组成 == {header} body {tail}
    • 示例 -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMYfnvWtC8Id5bPKae5yXSxQTt +Zpul6AnnZWfI2TtIarvjHBFUtXRo96y7hoL4VWOPKGCsRqMFDkrbeUjRrx8iL91 4/srnyf6sh9c8Zk04xEOpK1ypvBz+Ks4uZObtjnnitf0NBGdjMKxveTq+VE7BWUI yQjtQ8mbDOsiLLvh7wIDAQAB -----END PUBLIC KEY-----
  • DER

    • DER (Distinguished Encoding Rules) , 定义见维基百科-ASN.1.DER,是来自ASN.1 体系的一种二进制编码格式,常用于 windows/mac 的证书编码
    • 编码方式 == DER uses a pattern of type-length-value triplets
  • PEM与DER的关联

    • DER就是密钥的二进制表述格式。
    • PEM格式就是对DER编码转码为base64字符格式。通过base64解码可以还原DER格式。
    • PEM 是明文格式,可以包含证书或者是密钥;其内容通常是以类似 “—–BEGIN …—–” 开头 “—–END …—–” 为结尾的这样的格式进行描述的。因为DER是纯二进制格式,对人不友好,所以一般都用PEM进行存储。

4.5.2 CA中心采用的证书规范

4.5.2.1X.509[13]系列

1.X.209(1988)

ASN.1是描述在网络上传输信息格式的标准方法。它有两部分:第一部份(ISO 8824/ITU X.208)描述信息内的数据、数据类型及序列格式,也就是数据的语法;第二部分(ISO 8825/ITU X.209)描述如何将各部分数据组成消息,也就是数据的基本编码规则。

ASN.1原来是作为X.409的一部分而开发的,后来才独立地成为一个标准。这两个协议除了在PKI体系中被应用外,还被广泛应用于通信和计算机的其他领域。

2.X.500(1993)

X.500是一套已经被国际标准化组织(ISO)接受的目录服务系统标准,它定义了一个机构如何在全局范围内共享其名字和与之相关的对象。X.500是层次性的,其中的管理域(机构、分支、部门和工作组)可以提供这些域内的用户和资源信息。在PKI体系中,X.500被用来惟一标识一个实体,该实体可以是机构、组织、个人或一台服务器。X.500被认为是实现目录服务的最佳途径,但X.500的实现需要较大的投资,并且比其他方式速度慢;而其优势具有信息模型、多功能和开放性。

3.X.509(1993)

X.509是由国际电信联盟(ITU-T)制定的数字证书标准。在X.500确保用户名称惟一性的基础上,X.509为X.500用户名称提供了通信实体的鉴别机制,并规定了实体鉴别过程中广泛适用的证书语法和数据接口。

X.509的最初版本公布于1988年。X.509证书由用户公共密钥和用户标识符组成。此外还包括版本号、证书序列号、CA标识符、签名算法标识、签发者名称、证书有效期等信息。这一标准的最新版本是X.509 v3,它定义了包含扩展信息的数字证书。该版数字证书提供了一个扩展信息字段,用来提供更多的灵活性及特殊应用环境下所需的信息传送。

4.5.2.2公钥标准(Public Key Cryptography Standards)系列

以下是PKCS标准汇总,截图来自百度百科,这里简单了解一下即可。 在这里插入图片描述

4.5.2.3x509与PKCS对比

常见的有三种X.509证书,PKCS#12证书和PKCS#7证书。

  • X.509证书: 它仅包含了公钥信息而没有私钥信息。 X.509 DER 编码(ASCII)的后缀是: .DER .CER .CRT X.509 PAM 编码(Base64)的后缀是: .PEM .CER .CRT
  • PKCS#7 签名或加密。可以往里面塞x509,同时没有签名或加密内容。 PKCS#7可以封装一个或者多个X.509证书或者PKCS#6证书,并且可以包含CRL信息。PKCS#7证书中也不包含私钥信息。openssl提供了crl2pkcs7和pkcs7两个指令来生成和处理PKCS#7文件,可以使用他们在X.509证书和PKCS#7证书之间进行转换和处理 PKCS#7证书的后缀名是.p7b或.p7r 。
  • PKCS#8 PKCS#8标准是一个非常简单的标准,它主要用于封装私钥和其他相关的属性信息。一般来说,PKCS#8格式的私钥都是被加密的,支持PKCS#5和PKCS#12标准定义的算法,当然,私钥也可以不加密。PKCS#8标准一方面可以增强私钥的安全性,另一方面也为用户提供了一种简单的确立信任关系的方式,这主要是基于私钥特别名称和最高层可信者的权威公钥等属性信息。
  • PKCS#12证书: 含有私钥,同时可以有公钥,有口令保护。 PKCS12证书可以包含一个或者多个证书,并且还可以包含证书对应的私钥。openssl的pkcs12指令可以将X.509格式的证书和私钥封装成PKCS#12格式的证书,也可以将PKCS#12证书转换成X.509证书。 PKCS#12证书的后缀名通常是p12或者pfx。

X509是基本规范 P7和P12是两个实现规范,P7是数字信封,P12是带有私钥的证书规范。 它们之间可以进行相互转换。


5.常见算法

5.1对称加密算法

主要有DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法。 这里进行简单介绍一下基于“对称密钥”的加密算法。 基于“对称密钥”的加密算法主要有DES、TripleDES、RC2、RC4、RC5和Blowfish等。

  • 对称密钥:DES TripleDES算法 DES算法把64位的明文输入块变为数据长度为64位的密文输出块,其中8位为奇偶校验位,另外56位作为密码的长度。首先,DES把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,并进行前后置换,最终由L0输出左32位,R0输出右32位,根据这个法则经过16次迭代运算后,得到L16、R16,将此作为输入,进行与初始置换相反的逆置换,即得到密文输出。 DES算法具有极高的安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法,而56位长密钥的穷举空间为2^56,这意味着如果一台计算机的速度是每秒种检测100万个密钥,那么它搜索完全部密钥就需要将近2285年的时间,因此DES算法是一种很可靠的加密方法。
  • 对称密钥:RC算法 RC4算法的原理是“搅乱”,它包括初始化算法和伪随机子密码生成算法两大部分,在初始化的过程中,密钥的主要功能是将一个256字节的初始数簇进行随机搅乱,不同的数簇在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列,将得到的子密钥序列和明文进行异或运算(XOR)后,得到密文。 由于RC4算法加密采用的是异或方式,所以,一旦子密钥序列出现了重复,密文就有可能被破解,但是目前还没有发现密钥长度达到128位的RC4有重复的可能性,所以,RC4也是目前最安全的加密算法之一。
  • 对称密钥:BlowFish算法 [1] BlowFish算法是一个64位分组及可变密钥长度的分组密码算法,该算法是非专利的。 BlowFish算法使用两个“盒”:pbox[18]和sbox[4256],BlowFish算法有一个核心加密函数。该函数输入64位信息,运算后以64位密文的形式输出。用BlowFish算法加密信息,需要密钥预处理和信息加密两个过程。BlowFish算法的原密钥pbox和sbox是固定的,要加密一个信息,需要选择一个key,用这个key对pbox和sbox进行变换,得到下一步信息加密所用到的key_pbox和key_sbox。 BlowFish算法解密,同样也需要密钥预处理和信息解密两个过程。密钥预处理的过程和加密时完全相同。信息解密的过程就是把信息加密过程的key_pbox逆序使用即可。 以上内容来源自百度百科

5.2非对称加密算法

算法有RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)等。这里说下常见的算法:

  • RSA RSA 加密算法是目前最有影响力的公钥加密算法,并且被普遍认为是目前 最优秀的公钥方案 之一。RSA是第一个能同时用于 加密和数字签名 的算法,它能够抵抗到目前为止已知的 所有密码攻击,已被 ISO 推荐为公钥数据加密标准。 RSA 加密算法 基于一个十分简单的数论事实:将两个大 素数 相乘十分容易,但想要对其乘积进行 因式分解 却极其困难,因此可以将乘积 公开作为 加密密钥。
  • ECC ECC 也是一种 非对称加密算法,主要优势是在某些情况下,它比其他的方法使用 更小的密钥,比如 RSA 加密算法,提供 相当的或更高等级 的安全级别。不过一个缺点是 加密和解密操作 的实现比其他机制 时间长 (相比 RSA 算法,该算法对 CPU 消耗严重)。

5.3散列算法

  • MD5 MD5(信息-摘要算法5):MD5将任意长度的“字节串”映射为一个128bit的大整数。MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。也就是说无论是多长的输入,MD5 都会输出长度为128bits 的一个串 (通常用 16 进制 表示为 32 个字符)。
  • SHA1 SHA(安全哈希算法):Secure Hash Algorithm该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。可以对任意长度的数据运算生成一个160位的数值。SHA将输入流按照每块512位(64个字节)进行分块,并产生20个字节的被称为信息认证代码或信息摘要的输出。SHA-1是不可逆的、防冲突,并具有良好的雪崩效应。

SHA1 是和 MD5 一样流行的消息摘要算法,然而 SHA1 比 MD5 的 安全性更强。对于长度小于 2 ^ 64 位的消息,SHA1 会产生一个 160 位的消息摘要。基于 MD5、SHA1 的信息摘要特性以及 不可逆 (一般而言),可以被应用在检查 文件完整性以及数字签名等场景。但是在速度上,在相同的硬件上,SHA-1的运行速度比MD5慢。


已完结