X.509证书里有一段属性主题,大概是这样:

1
2
 C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft,
CN=www.freesoft.org/emailAddress=baccala@freesoft.org

这些 attribute 的含义是:

  • country (countryName, C),
  • organization (organizationName, O),
  • organizational unit (organizationalUnitName, OU),
  • distinguished name qualifier (dnQualifier),
  • state or province name (stateOrProvinceName, ST),
  • common name (commonName, CN) and
  • serial number (serialNumber).
  • locality (locality, L),
  • title (title),
  • surname (surName, SN),
  • given name (givenName, GN),
  • initials (initials),
  • pseudonym (pseudonym) and
  • generation qualifier (generationQualifier).
  • Distinguished Name (DN)。
    具体内容可以参考这里

PEM格式 - Privacy Enhanced Mail,打开看文本格式,以”——-BEGIN…”开头, “——-END…”结尾,内容是BASE64编码.

一个典型的场景,在为 node 设置启用 https 以前。

先要生成 ca 机构:

1
2
3
4
5
6
7
8
9
10
# 先生成一段私钥,大概也是一个取随机数的过程了。
openssl genrsa -out ca-key.pem -des 1024

# 用私钥生成 CSR
openssl req -new -key ca-key.pem -out ca-csr.pem

# 用 CSR 和私钥签署生成一个证书
openssl x509 -req -in ca-csr.pem -signkey ca-key.pem -out ca-cert.pem

# 到此我们有了一个 CA 证书,就有了一个 CA 机构。

你需要root或者admin的权限 Unable to load config info from /user/local/ssl/openssl.cnf 对于这个问题,你可以从网上下载一份正确的openssl.cnf文件, 然后set OPENSSL_CONF=openssl.cnf文件的本地路径

然后生成服务端证书:

1
2
3
4
5
6
# 还是先生成一个服务器端私钥,估计还是随机选一个随机数。
openssl genrsa -out server-key.pem 1024
# 用服务器端私钥,和 openssl 配置文件来生成一个新的 CSR
openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem
# 用 ca 的证书、 ca 的私钥和服务器的 csr(没有服务器的私钥)来生成服务器证书。这足以证明这个签发必须在 CA 方做,这可能也是 CA 收费的理由吧。
openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server-csr.pem -out server-cert.pem -extensions v3_req -extfile openssl.cnf

这里面用到的配置文件有一个特别重要的地方:

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
[req]  
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = BeiJing
localityName = Locality Name (eg, city)
localityName_default = YaYunCun
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Domain Control Validated
commonName = Internet Widgits Ltd
commonName_max = 64

[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
#注意这个IP.1的设置,IP地址需要和你的服务器的监听地址一样
IP.1 = 127.0.0.1

然后生成客户端证书:

1
2
3
4
5
6
# 还是先生成私钥
openssl genrsa -out client-key.pem
# 然后生成 csr
openssl req -new -key client-key.pem -out client-csr.pem
# 用 ca 的证书、ca 的私钥 客户端的 csr(又没用到客户端的私钥)来生成客户端证书。这足以证明这个签发必须在 CA 方做,这可能也是 CA 收费的理由吧
openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in client-csr.pem -out client-cert.pem

公私钥除了可以用来加解密信息,还可以用来做数字签名的签署和验证,一个典型流程大概是这样:

A 给 B 发信息:

  1. 首先 A 用 Hash 函数对要发送的数据实体生成摘要(digest),这个过程是不可逆的。
  2. A 使用自己的私钥对这个摘要进行加密,生成数字签名(signature),并将此签名连同要发送的数据实体一起发送给 B 。
  3. B 收到 A 发送过来的数据后,首先用 A 的公钥对数字签名进行解密,得到摘要,从而证明数据确实来自 A,因为只有 A 有私钥。
  4. B 再对接收到的数据实体进行 Hash 函数,如果得到的结果和上一步摘要一致,则证明数据实体没有被篡改过。