Certificate 证书

Dec 20, 2023 · 3 min read

基本概念

  • CRL(Certificate Revocation List 证书吊销列表) : PKI 系统中的一个结构化数据文件,该文件包含了证书颁发机构 (CA) 已经吊销的证书的序列号及其吊销日期
  • CA(Certificate Authority): 证书的签发机构,它是公钥基础设施(Public Key Infrastructure,PKI)的核心。 任何个体/组织都可以扮演 CA 的角色,只不过难以得到客户端的信任,能够受浏览器默认信任的 CA 大厂商有很多,其中 TOP5 是 Symantec、Comodo、Godaddy、GolbalSign 和 Digicert
  • PKCS(The Public-Key Cryptography Standards 公钥密码学标准): 是一组由RSA Security Inc.设计和发布的公钥密码标准。
  • X.509标准是Public Key Certificates公钥证书的格式标准
  • Certificate Trust Chain(证书信任链): 用于身份验证的一系列证书,它们形成一条从一个可信任的根证书颁发机构开始,逐级向下连接,直到用于验证某个特定证书的中间证书或终端证书的一种方式
  • Digital Certificate 数字证书又称为公开密钥证书(Public key certificate):用来证明公开密钥拥有者的身份。
  • ASN.1(Abstract Syntax Notation One 抽象语法标记):一种 ISO/ITU-T 标准,描述了一种对数据进行表示、编码、传输和解码的数据格式。第一代PKI标准主要是基于抽象语法符号(Abstract Syntax Notation One,ASN.1)编码的,实现比较困难,这也在一定程度上影响了标准的推广。

服务器证书分类

screen reader text
服务器证书分类

  • DV(Domain Validation):面向个体用户,安全体系相对较弱,验证方式就是向 whois 信息中的邮箱发送邮件,按照邮件内容进行验证即可通过;
  • OV(Organization Validation):面向企业用户,证书在 DV 证书验证的基础上,还需要公司的授权,CA 通过拨打信息库中公司的电话来确认;
  • EV(Extended Validation):打开 Github 的网页,你会看到 URL 地址栏展示了注册公司的信息,这会让用户产生更大的信任,这类证书的申请除了以上两个确认外,还需要公司提供金融机构的开户许可证,要求十分严格

数字证书编码格式

X.509 证书目前有以下两种编码格式:

  • PEM - Privacy Enhanced Mail 保密增强邮件协议,以”—–BEGIN…”开头,”—–END…” 结尾,内容以 BASE64 编码。Apache 和 *NIX 服务器偏向于使用这种编码格式。
-----BEGIN Type-----
Headers
base64-encoded Bytes
-----END Type-----
  • DER - Distinguished Encoding Rules,二进制格式,不可读。Java 和 Windows 服务器偏向于使用这种编码格式

扩展名

除了 .pem 及 .der 之外,不同的系统或程序对数字证书文件载体定义了自己的扩展名,它们除了格式不同之外,内容也有差别,但大多数都能相互转换:

  • .crt: 多见于 *NIX 系统 PEM 编码
  • .cer: 多见于 Windows 系统 DER 编码
  • .csr: (Certificate Signing Request 证书签名请求),是向 CA 发出的证书申领请求,其核心内容包含一个「公钥」及其他主体信息,在生成该请求时,也会生成相应的「私钥」

go 语言 x509 包

crypto/x509 包主要用于解析 X.509 编码的密钥和证书.

crypto/x509/pkix 包含用于 X.509 证书,CRL 和 OCSP 的 ASN.1 解析和序列化的共享低级结构。

// X509 证书
type Certificate struct {
    // 证书的 subject 信息,包含 CN,O,L,S,C等字段
    Subject pkix.Name
    // contains filtered or unexported fields
}


// 证书签署请求
type CertificateRequest struct {
    // 签名
    Signature          []byte
    // 签名算法
    SignatureAlgorithm SignatureAlgorithm
    // 私钥算法
    PublicKeyAlgorithm PublicKeyAlgorithm
    // 私钥
    PublicKey          interface{}
    // 证书签署请求的 subject
    Subject pkix.Name
    // contains filtered or unexported fields
}
type Name struct {
	Country, Organization, OrganizationalUnit []string
	Locality, Province                        []string
	StreetAddress, PostalCode                 []string
	SerialNumber, CommonName                  string

	// Names contains all parsed attributes. When parsing distinguished names,
	// this can be used to extract non-standard attributes that are not parsed
	// by this package. When marshaling to RDNSequences, the Names field is
	// ignored, see ExtraNames.
	Names []AttributeTypeAndValue

	// ExtraNames contains attributes to be copied, raw, into any marshaled
	// distinguished names. Values override any attributes with the same OID.
	// The ExtraNames field is not populated when parsing, see Names.
	ExtraNames []AttributeTypeAndValue
}

CloudFlare 开源证书管理工具 cfssl

cfssl 第三方使用–kubeasz 部署 k8s 集群

[root@master-01 bin]# ./cfssl version
Version: dev
Runtime: go1.22.8
[root@master-01 bin]# ./cfssl --help
version # 查看 cfssl 版本
selfsign # 生成一个新的自签名密钥和签名证书
certinfo # 输出给定证书的证书信息, 跟 cfssl-certinfo 工具作用一样
print-defaults # 打印json格式的模板-ca签名配置文件和客户端证书请求文件
  # config:生成ca配置模板文件
  # csr:生成证书请求模板文件
gencert # 生成新的key(密钥)和签名证书
  # -initca:初始化一个新ca (默认false,需要指定ca证书用以前面其他证书)
  # -ca:ca的证书
  # -ca-key:ca的私钥文件
  # -config:请求证书的json文件
  # -profile:与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息
sign # 签名一个客户端证书,通过给定的CA和CA密钥,和主机名
revoke # 吊销证书
info # 获取签名者信息
bundle # 创建包含客户端证书的证书包
serve # 启动一个HTTP API服务
genkey  # 生成一个key(私钥)和csr(证书签名请求)
gencsr # 生成新的证书请求文件
gencrl # 生成新的证书吊销列表

准备的配置: https://github.com/easzlab/kubeasz/blob/4910805e1bfc2de6b239a082b056290bb54d311a/roles/deploy/templates/ca-csr.json.j2

{
  "CN": "kubernetes-ca",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "HangZhou",
      "L": "XS",
      "O": "k8s",
      "OU": "System"
    }
  ],
  "ca": {
    "expiry": "{{ CA_EXPIRY }}"
  }
}

https://github.com/easzlab/kubeasz/blob/41c047b3f098cbbbb3fadd93e1749345a487b8b9/roles/deploy/templates/ca-config.json.j2

{
  "signing": {
    "default": {
      "expiry": "{{ CERT_EXPIRY }}"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "{{ CERT_EXPIRY }}"
      },
      "kcfg": {
        "usages": [
            "signing",
            "key encipherment",
            "client auth"
        ],
        "expiry": "{{ CUSTOM_EXPIRY }}"
      }
    }
  }
}

https://github.com/easzlab/kubeasz/blob/b51f7222020cb39477b574d354fd5e9460061f63/roles/deploy/templates/admin-csr.json.j2

{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "HangZhou",
      "L": "XS",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

生成 CA 证书

# https://github.com/easzlab/kubeasz/blob/ebf4f1e5072aedddf1786f6857d79a23403faa57/roles/deploy/tasks/main.yml

- name: 准备CA配置文件和签名请求
  template: src={{ item }}.j2 dest={{ cluster_dir }}/ssl/{{ item }}
  with_items:
    - "ca-config.json"
    - "ca-csr.json"
  when: "p.stat.isreg is not defined or CHANGE_CA|bool"
  tags: force_change_certs
  
- name: 生成 CA 证书和私钥
  when: "p.stat.isreg is not defined or CHANGE_CA|bool"
  tags: force_change_certs
  shell: "cd {{ cluster_dir }}/ssl && \
	 {{ base_dir }}/bin/cfssl gencert -initca ca-csr.json | {{ base_dir }}/bin/cfssljson -bare ca" 

客户端证书生成

# https://github.com/easzlab/kubeasz/blob/16b98e41ff61b186df4111a3d13b93a1ba29569f/roles/deploy/tasks/create-kubectl-kubeconfig.yml
- name: 准备kubectl使用的admin证书签名请求
  template: src=admin-csr.json.j2 dest={{ cluster_dir }}/ssl/admin-csr.json

- name: 创建admin证书与私钥
  shell: "cd {{ cluster_dir }}/ssl && {{ base_dir }}/bin/cfssl gencert \
        -ca=ca.pem \
        -ca-key=ca-key.pem \
        -config=ca-config.json \
        -profile=kubernetes admin-csr.json | {{ base_dir }}/bin/cfssljson -bare admin"

参考

Danny
Authors
Devops
Life is short 人生苦短,及时行乐.