关于证书,这里有你想知道的一切

java初学者

共 5307字,需浏览 11分钟

 ·

2022-05-23 18:34

关于证书,这里有你想知道的一切

概览

481177129868b8ba5ad27dfc983e2a20.webp


术语

下列的某些术语其实在Java的权限控制框架中也经常见到;

实体(entity)

entity可以是任何东西,即使是虚拟的,例如:

  • 每个人类个体是一个entity;

  • 你的计算机也是一个entity;

  • 一个小狗是一个entity;

  • 甚至神话传说中的孙悟空等也可以是一个entity;

身份(identity)

官方定义:一个或多个实体以一个或多个属性的形式表示的一个实体,这些属性允许实体在上下文中充分区分;

举例:例如你在学校,是一个学生xxx的身份,而你在家里,又是子女的身份;更细化一些,你在学校,身高185,长像彭于晏,那你就是标准的帅哥同学的身份;

身份标识符(identifier)

身份标识符被定义为一系列数字、字符和符号或任何其他形式的数据,这些数据可以用来识别各个entity;一个身份可能会对应多个entity,但是一个身份标识符会唯一对应一个entity,例如学校里边学生身份的人很多,但是学号是xxx的学生只有一个;

声明(claim)和认证(authentication)

一个实体可以声明(claim)说他拥有某些东西,而其他实体能对这个声明进行认证(authenticate),以确认声明的真实性;通常认证的目的就是确认声明的合法性;

subscriber & CA & relying party(RP)

能作为一个证书的subject的entity,称为subscriber(证书owner)或者end entity;

对应地,subscriber 的证书有时也称为 end entity certificates 或 leaf certificates, 原因在后面讨论 certificate chains 时会介绍。

CA(certificate authority,证书权威)是给 subscriber 颁发证书的实体,是一种 certificate issuer(证书颁发者)。

CA 的证书,通常称为root certificate或 intermediate certificate,具体取决于 CA 类型。

Relying party 是使用证书的用户(certificate user),它验证由 CA 颁发(给 subscriber)的证书是否合法。

一个 entity 可以同时是一个 subscriber 和一个 relying party。也就是说,单个 entity 既有自己的证书,又使用其他证书来认证 remote peers, 例如双向 TLS(mutual TLS,mTLS)场景。

公钥加密(Public key cryptography)及PKCS

证书(certificate)和PKI的基础是公钥加密(public key cryptography),也叫非对称加密(asymmetric cryptography);

公钥加密的理论基础非常复杂,但是如果只是使用,我们并不需要了解其每一步数学原理,只需要知道其能做什么即可;

PKCS

我们可以在很多地方看到PKCS,PKCS是公钥加密标准,PKCS全称是Public-Key Cryptography Standards,由RSA实验室与其他安全系统开发商为促进公钥加密的发展而定制的一系列标准,PKCS目前共发布过15个标准:

  • PKCS#1:RSA Cryptography Standard,定义了RSA Public Key和Private Key数学属性和格式。详见RFC8017;

  • PKCS#3:定义Diffie-Hellman密钥交换协议。

  • PKCS#5:描述一种利用从口令派生出来的安全密钥加密字符串的方法。使用MD2或MD5 从口令中派生密钥,并采用DES-CBC模式加密。主要用于加密从一个计算机传送到另一个计算机的私人密钥,不能用于加密消息。

  • PKCS#6:描述了公钥证书的标准语法,主要描述X.509证书的扩展格式。

  • PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码操作,就可以将加密的消息转换成PEM消息。常用的后缀是:.P7B .P7C .SPC;PKCS#7以树状展示证书链,同时也支持单个证书;

  • PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。详见RFC5858;

  • PKCS#9:定义一些用于PKCS#6证书扩展、PKCS#7数字签名和PKCS#8私钥加密信息的属性类型。

  • PKCS#10:描述证书请求语法(CSR)。

  • PKCS#11:称为Cyptoki,定义了一套独立于技术的程序设计接口,用于智能卡和PCMCIA卡之类的加密设备。

  • PKCS#12:描述个人信息交换语法标准。描述了将用户公钥、私钥、证书和其他相关信息打包的语法,定义了通常用于存储公钥/私钥的文件格式,使用基于密码的对称密钥进行保护,PKCS#12文件实际上是一个KeyStore,详见RFC292。常用的后缀有:.P12 .PFX;PS:通常Java中使用的jks文件属于Java自己定义的格式与p12文件可以互相转换,但是不能直接使用;

  • PKCS#13:椭圆曲线密码体制标准。

  • PKCS#14:伪随机数生成标准。

  • PKCS#15:密码令牌信息格式标准。

密钥对

公钥加密系统使用密钥对(key pair)来加解密,一个密钥对包含:

  • 一个私钥,解密用,不能公开;

  • 一个公钥,可以分发给任何人,加密用;

密钥可以做的事情:

  • 加解密;公钥加密私钥解密;

  • 签名:私钥签名公钥验签;

公钥加密解决的问题

在没有公钥加密只有对称加密的时候,如果我们想要在不安全的网络上互相安全的通信,则需要将我们的消息加密,加密就需要交换密钥,而由于网络是一个不安全的信道,如果我们在网络上直接交换密钥可能会被恶意攻击者截获,一旦密钥被截获,恶意攻击者就能随时解密我们的消息,而使用公钥加密就不存在该问题,我们可以大胆的将公钥在网络上分发给别人,而不用担心其被截获,因为公钥加密的内容只有私钥能解密,而私钥只有我们自己有;

用一句话概括:公钥加密解决了在不安全信道上如何交换密钥的问题;

实际应用中密钥交换不仅仅是将公钥分发出去这么简单,详细可以参考通过局域网中间人攻击学网络第四篇

证书

前边说到如果想要在不安全的网络上实现安全通信,需要用到公钥加密,把公钥给别人,而仅仅是公钥给别人的话包含的信息又太少了,比如如果别人想要知道你是谁,这个在公钥上是没办法得到的,而证书则解决了这个问题,证书规定了在交换公钥的时候还应该给别人哪些信息,这里证书其实是一个包含公钥的数据结构,描述了里边包含的内容,例如包含公钥、姓名/公司名等;

虽然证书中已经包含了公钥信息和所有者等信息,我们可以将证书分发给其他人来进行安全通信,但是如何让别人信任这个证书的信息呢?即如何给使用者证明这个证书就是你的,而不是其他人伪造的,这就引入了权威机构(CA)的概念,假设我们两个都信任一个权威结构,那么我们可以让权威机构给我们的证书进行签名,然后将签名附加到证书中,这样使用者就可以对签名进行校验,如果是其信任的权威机构的签名则认为证书的信息是真实的;

总结来说,证书就是将名字(和其他一些信息)关联到公钥上的东西;

PS:权威机构就类似公安机关,我们经常会从网上看到一些奇葩新闻,即某些机构要求证明你就是你,而证明方法就是让公安机关开具证明,这里公安机关就类似一个权威机构;

X.509证书

一般来说,当我们提到证书一词,并且没有添加额外的限定词时,指的都是X.509 v3证书,更准确地说,他们指的是RFC5280中描述、 CA/Browser Forum Baseline Requirements中进一步完善的 PKIX 变种。所以当你看到PKIX Certificate字样的时候可以认为就是X.509 Certificate。

证书中提到了证书就是将名字等信息关联到公钥上的东西,证书实际上就是一个包含公钥的数据结构,而证书中都有哪些信息则是更具体的规范中定义的,我们最常用的就是X.509 v3证书规范;

历史简介:X.509 在1988年作为国际电信联盟(ITU)X.500 项目的一部分首次标准化。这是通信(telecom)领域的标准,想通过它构建一个全球电话簿(global telephone book)。虽然这个项目没有成功,但却留下了一些遗产,X.509 就是其中之一;如果查看 X.509 的证书,会看到其中包含了 locality、state、country 等信息, 之前可能会有疑问为什么为 web 设计的证书会有这些东西,现在应该明白了,因为X.509 并不是为 web 设计的。

X.509 v3证书是构建在ASN.1编码规范上的,ASN.1编码规范后续介绍;

X.509常见后缀:

  • X.509 DER 编码(ASCII)的后缀是:.DER .CER .CRT

  • X.509 PAM 编码(Base64)的后缀是:.PEM .CER .CRT

ASN.1编码

ASN.1是一种用来定义数据结构的接口描述语言,它不是二进制,也不是文件格式,本身只定义了表示信息的抽象句法;标准ASN.1编码规则有BER(Basic Encoding Rules)、CER(Canonical Encoding Rules)、DER(Distinguished Encoding Rules)、PER(Packed Encoding Rules)、XER(XML Encoding Rules);

也就是说ASN.1是来描述一个事物的,例如用ASN.1来定义一个人,包含姓名、身高、性别等属性,但是如何将这些数据传给别人,就需要具体的编码规则了,具体的编码规则再将这些信息转换为可传输的二进制数据来传输给别人;更贴近点儿我们的代码,就像你有一个内存实体,在远程调用的时候需要传给别人,那你就要定义这个实体如何序列化,这样接收方才能接收,例如你用protocol buf来传输,而在这里,ASN.1就相当于这个内存实体的定义,而具体的编码规则则相当于protocol buf;

PEM

PEM是一个用来存储和发送密码学key、证书和其他数据的文件格式的事实标准。许多使用ASN.1的密码学标准(比如X.509和PKCS)都使用DER编码,而DER编码的内容是二进制的,不适合与邮件传输(早期Email不能发送附件),因此使用PEM把二进制内容转换成ASCII码。文件内容的格式像下面这样:

-----BEGIN label-----
BASE64Encoded
-----END label-----

label用于区分内容到底是什么类型,与PEM相关的RFC有很多,与文本相关的是RFC7468,里边规定了很多label;注意,不是所有label都有对应的RFC,这些label只是一种约定俗成;

PEM实际上就是把DER编码的文件的二进制内容用base64编码一下,然后加上-----BEGIN label-----这样的头和-----END label-----这样的尾,中间则是DER文件的Base64编码。

不幸的是,即使是这样简单的规范,其中的label并不统一,相同的内容在不同的实现下label可能并不一致;

PKI

公钥基础设施(PKI, 全称 public key infrastructure)是创建、管理、分发、使用、存储和撤销数字证书以及管理公钥加密所需的一组角色、策略、硬件、软件和过程。

证书是大部分PKI的构建模块,而证书权威是其基础;

自己从头构建PKI是一件极其庞大的工作,但实际上一些简单的PKI甚至并不使用证书,例如:

  • 编辑~/.ssh/authorized_keys文件时,就是在配置 一个简单的无证书形式的(certificate-less)PKI,SSH 通过这种方式在扁平文件内实现 public key 和 name 的绑定;

  • PGP 用证书,但不用 CA,而是用一个 web-of-trust model;

trust store

通过前面的介绍,证书可以解读为一个claim,Issuer 会对这份声明进行签名,relying party 能(通过 issuer 的公钥)验证(authenticate)签名是否合法。但这里其实跳过了一个重要问题:relying party 是如何知道 issuer 的公钥的?

答案其实很简单,就是relying parties在自己的trust store(信任库)预置了一个他信任的根证书列表;

当我们添加自签名证书到信任列表中时,就是将其添加到我们系统的trust store中;


联系我
  • 作者微信:JoeKerouac

  • 微信公众号(文章会第一时间更新到公众号,如果搜不出来可能是改名字了,加微信即可=_=|):代码深度研究院

  • GitHub:https://github.com/JoeKerouac


浏览 9
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报