草庐IT

一文了解数字签名、数字证书、自签证书

oceanweave 2023-04-08 原文

参考

一、数字证书与数字签名

通俗理解:

  • 数字证书相当于【身份证】 —— 确认你是谁
    • 依照《电子签名法》的规定,从事电子认证业务需要行政许可,经许可的第三方认证机构即为通常所称的CA机构,而经CA机构认证并与当事人主体相关联的字符串,就是“数字证书”,电子认证的过程也就是数字证书的申请与颁发过程。
    • 用于确认身份
  • 数字签名相当于【持身份证进行签名】—— 作用对消息内容进行确认,确认的确是某人自愿签名,或是确实是某人发的消息
    • 使用数字证书的签名也就是数字签名,根据全国人大《电子签名法释义》第十六条的解释,数字签名是指通过使用非对称密码加密系统对电子记录进行加密、解密变换来实现的一种电子签名。
    • 可用于确认内容的可靠性,或用于确认签名的自愿性

1. 数字证书

数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。简单地说,数字证书是一段包含用户身份信息、用户公钥信息以及份验证机构数字签名的数据。

它主要包含:

证书的版本信息;
证书的序列号,每个证书都有一个唯一的证书序列号;
证书所使用的签名算法;
证书的发行机构名称;
证书的有效期;
证书所有人的名称;
证书所有人的密钥对;
证书发行者对证书的签名。

2. 数字签名的原理

数字签名是基于非对称密钥加密技术与数字摘要技术的应用,是一个包含电子文件信息以及发送者身份,并能够鉴别发送者身份以及发送信息是否被篡改的一段数字串。一段数字签名数字串,包含了电子文件经过Hash编码后产生的数字摘要,即一个Hash函数值以及发送者的公钥和私钥三部分内容。发送方通过私钥加密后发送给接收方,接收方使用公钥解密,通过对比解密后的Hash函数值确定数据电文是否被篡改。

3. 数字签名和数字证书的关系

数字签名和数字证书的目的:

  • 数字签名保证内容是真实的,没有被篡改
  • 数字证书验证【内容的签署者】是否是【证书的登记者】

以场景为例:用户A向用户B发送一段内容,但不想被窃取或篡改

  1. 首先用户A对此内容进行 hash 运算【提取出摘要(hash值,就是一字符串)】,之后对此 hash 值用【自己的私钥】进行加密 —— 形成了数字签名
  2. 之后用户A 将【数字签名(加密的内容hash值)】和【内容原文】一起发送给用户 B
  3. 用户B通过之前用户A发送过来的证书 —— 获取【用户A的公钥】
    • 此处证书的真伪,通过【公证机构CA】来辨别,每台机器上会【内置CA机构的证书,用来验证用户传来的证书】
    • 此处证书确保了【用户A的公钥正确性,也就是用户A的身份真实性】
  4. 用户B通过【证书中的公钥】,解开【数字签名(加密的内容hash值)】,获得【未加密的内容hash值】
  5. 用户B通过与用户A相同的 hash 函数对【内容原文】进行hash运算,得到【摘要(hash值,就是一字符串)】,与步骤4中获取的【未加密的内容hash值】进行比较,从而判别内容是否被篡改

其中涉及的 hash 函数、证书等,都是通过 https TLS协商阶段传递的

TLS 握手详细过程

下面来看 TLS 握手的详细过程 (:此图与HTTPS详解一中的 HTTPS 原理图的流程大致相同,不同的是此图把重点放在了TLS握手的相关概念上):

SSL / TLS 握手详细过程

  1. **"client hello"消息:**客户端通过发送"client hello"消息向服务器发起握手请求,该消息包含了客户端所支持的 TLS 版本和密码组合以供服务器进行选择,还有一个"client random"随机字符串。
  2. **"server hello"消息:**服务器发送"server hello"消息对客户端进行回应,该消息包含了数字证书,服务器选择的密码组合和"server random"随机字符串。
  3. **验证:**客户端对服务器发来的证书进行验证,确保对方的合法身份,验证过程可以细化为以下几个步骤:
    1. 检查数字签名
    2. 验证证书链 (这个概念下面会进行说明)
    3. 检查证书的有效期
    4. 检查证书的撤回状态 (撤回代表证书已失效)
  4. **“premaster secret"字符串:**客户端向服务器发送另一个随机字符串"premaster secret (预主密钥)”,这个字符串是经过服务器的公钥加密过的,只有对应的私钥才能解密。
  5. **使用私钥:**服务器使用私钥解密"premaster secret"。
  6. 生成共享密钥:客户端和服务器均使用 client random,server random 和 premaster secret,并通过相同的算法生成相同的共享密钥 KEY
  7. **客户端就绪:**客户端发送经过共享密钥 KEY加密过的"finished"信号。
  8. **服务器就绪:**服务器发送经过共享密钥 KEY加密过的"finished"信号。
  9. **达成安全通信:**握手完成,双方使用对称加密进行安全通信。

二、证书

1. 证书相关文件格式

证书相关文件有多种格式,常见格式:.crt.key.req.csr.pem.der

证书类型
xx.crtxx.cert证书文件CA认证后的证书文件,包含公钥,签名和其他需要认证的信息,比如主机名称(IP)等
xx.key私钥文件通常是rsa算法,分带口令和不带口令的版本
xx.csrxx.req证书请求文件里面包含公钥和其他信息,通过签名后就可以生成证书;
用于向证书颁发机构申请crt证书时使用,服务器配置时不会用到;
在制作csr文件的时,必须使用自己的私钥来签署申,还可以设定一个密钥;
证书保存格式
xx.pem文本格式里面一般包含私钥和证书的信息
xx.derxx.cer二进制格式只含有证书信息,不包含私钥
xx.PFXxx.P12二进制格式同时包含证书和私钥,且一般有密码保护
备注
根证书文件(ca.crt)和根证书对应的私钥文件(ca.key由 CA(证书授权中心,国际认可)生成和保管,用于验证其他证书的合法性

实际上,上述文件的扩展名可以随意命名。只是为了容易理解文件的功能而选择大家都认识的命名方式。但是,上述文件是有格式的,只能是 pem 格式或者 der 格式。使用什么格式的文件取决于需求。

pem 格式的文件为文本文件,内容分别为:

下面几种类型文件,主要是首尾命名不同

证书文件:

-----BEGIN CERTIFICATE-----
MIIFjzCCBHegAwIBAgIQDHZBMYiVhBUfylD2vwLBETANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMTgxMTExMDAwMDAwWhcNMTkxMTExMTIwMDAwWjA
-----END CERTIFICATE-----

私钥文件:

-----BEGIN RSA PRIVATE KEY-----
MIIFjzCCBHegAwIBAgIQDHZBMYiVhBUfylD2vwLBETANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMTgxMTExMDAwMDAwWhcNMTkxMTExMTIwMDAwWjA
-----END RSA PRIVATE KEY-----

请求文件:

-----BEGIN CERTIFICATE REQUEST-----
MIIFjzCCBHegAwIBAgIQDHZBMYiVhBUfylD2vwLBETANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMTgxMTExMDAwMDAwWhcNMTkxMTExMTIwMDAwWjA
-----END CERTIFICATE REQUEST-----   

2. 证书种类

证书分为根证书、服务器证书、客户端证书。根证书文件(ca.crt)和根证书对应的私钥文件(ca.key)由 CA(证书授权中心,国际认可)生成和保管。那么服务器如何获得证书呢?向 CA 申请!步骤如下:

  1. 服务器生成自己的公钥(server.pub)和私钥(server.key)。后续通信过程中,客户端使用该公钥加密通信数据,服务端使用对应的私钥解密接收到的客户端的数据
  2. 服务器使用公钥生成请求文件(server.req),请求文件中包含服务器的相关信息,比如域名、公钥、组织机构等;
  3. 服务器将 server.req 发送给 CA。CA 验证服务器合法后,使用 ca.keyserver.req 生成证书文件(server.crt)——使用私钥生成证书的签名数据;
  4. CA 将证书文件(server.crt)发送给服务器。

由于ca.keyca.crt 是一对,ca.crt 文件中包含公钥,因此 ca.crt 可以验证 server.crt是否合法——使用公钥验证证书的签名。

3. 验证方式

验证方式分为单向验证和双向验证。

3.1 单向验证

单向验证是指通信双方中一方验证另一方是否合法。通常是指客户端验证服务器

客户端需要:ca.crt

服务器需要:server.crtserver.key

PS:我们平时使用 PC 上网时使用的就是单向验证的方式。即,我们验证我们要访问的网站的合法性。PC 中的浏览器(火狐、IE、chrome等)已经包含了很多 CA 的根证书(ca.crt)。当我们访问某个网站(比如:https://www.baidu.com)时,网站会将其证书(server.crt)发送给浏览器,浏览器会使用 ca.crt 验证 server.crt 是否合法。如果发现访问的是不合法网站,浏览器会给出提示。

现实中,有的公司会使用自签发证书,即公司自己生成根证书(ca.crt)。如果我们信任此网站,那么需要手动将其证书添加到系统中。

3.2 双向验证

双向验证是指通信双方需要互相验证对方是否合法。服务器验证客户端,客户端验证服务器。

客户端需要:ca.crtclient.crtclient.key

服务器需要:ca.crtserver.crtserver.key

双向验证通常用于支付系统中,比如支付宝。我们在使用支付宝时必须下载数字证书,该证书就是支付宝颁发给针对我们这台机器的证书,我们只能使用这台机器访问支付宝。如果换了机器,那么需要重新申请证书。

三、Linux 自签名生成证书

x509证书通常会用到三类文:key,csr,crt

*.key:密钥文件,一般是SSL中的私钥,通常是rsa算法,分带口令和不带口令的版本;

*.csr:证书请求文件,里面包含公钥和其他信息,通过签名后就可以生成证书;用于向证书颁发机构申请crt证书时使用,服务器配置时不会用到;在制作csr文件的时,必须使用自己的私钥来签署申,还可以设定一个密钥;

*.crt, *.cert:CA认证后的证书文件,包含公钥,签名和其他需要认证的信息,比如主机名称(IP)等;

*.pem:里面一般包含私钥和证书的信息;

我们自签名证书配置,虚拟主机需要的是 .crt证书,和不带口令的SSL Key的.key文件;

0. keytool / openssl

keytoolopenssl是俩个证书管理工具,keytooljava JDK自带的证书管理工具,使用keytool可以生成密钥,创立证书。只需装了jdk,并正确设置了环境变量,即可以之间通过命令行执行keytool命令来管理证书。 openssl则是一个开源的安全套接字层密码库,功能比keytool更加丰富。

1. 生成 key

[root@VM-1-14-centos key]# openssl genrsa -des3 -out server.key 2048
Generating RSA private key, 2048 bit long modulus
...........+++
....+++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:
[root@VM-1-14-centos key]# ls
server.key
复制代码

这样是生成rsa私钥,des3算法,openssl格式,2048位强度。server.key是密钥文件名。为了生成这样的密钥,需要一个至少四位的密码。

可以通过以下方法生成没有密码的key:

[root@VM-1-14-centos key]# openssl rsa -in server.key -out server.key
Enter pass phrase for server.key:
writing RSA key
[root@VM-1-14-centos key]# ls
server.key
复制代码

server.key 就是没有密码的版本了。

2. 生成CA的crt

[root@VM-1-14-centos key]# openssl req -new -x509 -key server.key -out ca.crt -days 3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
[root@VM-1-14-centos key]# ls
ca.crt  server.key

生成的 ca.crt 文件是用来签署下面的 server.csr 文件。

3. 生成csr

[root@VM-1-14-centos key]# openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
# 填写证书请求文件的信息
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shaanxi
Locality Name (eg, city) [Default City]:Xi'an
Organization Name (eg, company) [Default Company Ltd]:cloudcared
Organizational Unit Name (eg, section) []:section
Common Name (eg, your name or your server's hostname) []:www.ssltest.com  # 注意此处,该证书作用在此域名上
Email Address []:honest1y@cloudcared.cn 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@VM-1-14-centos key]# ls
ca.crt  server.csr  server.key

须要依次输入国家,地区,组织,Email。最重要的是common name,能够写你的名字或者域名。

若是为了https申请,这个必须和域名吻合,不然会引起浏览器警报。生成的 csr 文件交给 CA签名 后造成服务端本身的证书。

4. 生成crt

CSR文件必须有CA的签名才可形成证书,可将此文件发送到verisign等地方由它验证,要交一大笔钱,何不自己做CA呢。

[root@VM-1-14-centos key]# openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey server.key -CAcreateserial -out server.crt
Signature ok
subject=/C=CN/ST=Shaanxi/L=Xi'an/O=cloudcared/OU=section/CN=www.ssltest.com/emailAddress=honest1y@cloudcared.cn
Getting CA Private Key
[root@VM-1-14-centos key]# ls
ca.crt  ca.srl  server.crt  server.csr  server.key

输入key的密钥后,完成证书生成。

-CA 选项指明用于被签名的csr证书

-CAkey 选项指明用于签名的密钥

-CAserial 指明序列号文件,序列号文件是ca指令签发证书的时候的依据文件之一,它从该文件读取当前签发的证书的序列号并将序列号文件中的序列号加1,这样,就可以确保证书的序论号是递增的,不会重复。

-CAcreateserial 指明文件不存在时自动生成

最后生成了私用密钥:server.key和本身认证的SSL证书:server.crt

证书合并:

cat server.key server.crt > server.pem

有关一文了解数字签名、数字证书、自签证书的更多相关文章

  1. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  2. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  3. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  4. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  5. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  6. ruby - 按数字(从大到大)然后按字母(字母顺序)对对象集合进行排序 - 2

    我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby​​做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排

  7. ruby-on-rails - rails 中的正则表达式匹配 [\w] 和 "-"但不匹配数字 - 2

    我想为名字验证编写一个正则表达式。正则表达式应包括所有字母(拉丁/法语/德语字符等)。但是我想从中排除数字并允许-。所以基本上它是\w(减)数(加)-。请帮忙。 最佳答案 ^[\p{L}-]+$\p{L}匹配anykindofletterfromanylanguage. 关于ruby-on-rails-rails中的正则表达式匹配[\w]和"-"但不匹配数字,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  8. ruby-on-rails - 将数字字符串转换为数字数组 - 2

    在我的应用程序中,我有一个文本字段,用户可以在其中输入类似这样的内容"1,2,3,4"存储到数据库中。现在,当我想使用内部数字时,我有两个选择:"1,2,3,4".split(',')或string.scan(/\d+/)do|x|a两种方式我都得到一个像这样的数组["1","2","3","4"]然后我可以通过在每个数字上调用to_i来使用这些数字。有没有更好的方法可以转换"1,2,3"to[1,2,3]andnot["1","2","3"] 最佳答案 str.split(",").map{|i|i.to_i}但是这个想法对你来说

  9. ruby-on-rails - 如何测试自己对 Ruby/ROR 的了解? - 2

    是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby​​和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T

  10. ruby - 递归地将所有数字字符串转换为 Ruby 哈希中的整数 - 2

    我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj

随机推荐