很久之前没改动的一个项目,今天跑起来突然报错:x509: certificate relies on legacy Common Name field, use SANs instead,这到底是怎么回事呢?问题出现在哪里?该如何解决?

问题查找分析:

在官方 https://go.dev/doc/go1.15#commonname 找到这个资料

1
2
3
4
X.509 CommonName deprecation
The deprecated, legacy behavior of treating the CommonName field on X.509 certificates as a host name when no Subject Alternative Names are present is now disabled by default. It can be temporarily re-enabled by adding the value x509ignoreCN=0 to the GODEBUG environment variable.

Note that if the CommonName is an invalid host name, it's always ignored, regardless of GODEBUG settings. Invalid names include those with any characters other than letters, digits, hyphens and underscores, and those with empty labels or trailing dots.

意思是说go1.15版本及以后CommonName这个字段已经过时,可以通过设置GODEBUG环境变量临时开启:

1
x509ignoreCN=0

解决办法:

生成证书时使用SANs代替

新增文件genca-v3.ext

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[ alt_names ]
DNS.1 = mydomain.com
DNS.2 = *.mydomain.com


[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
#extendedKeyUsage = critical, timeStamping, serverAuth, clientAuth
subjectAltName = @alt_names

生成证书时指定该扩展文件

1
2
3
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=mydomain.com" -out server.csr
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile genca-v3.ext -extensions v3_req -out server.crt

网上参考另一种命令写法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
生成默认 ca:
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=example.ca.com" -days 5000 -out ca.crt

生成证书
openssl req -new -sha256 \
    -key ca.key \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=UnitedStack/OU=Devops/CN=www.example.com" \
    -reqexts SAN \
    -config <(cat /System/Library/OpenSSL/openssl.cnf \
        <(printf "[SAN]\nsubjectAltName=DNS:www.example.com,DNS:www.example2.com")) \
    -out example.csr    

签名证书
openssl x509 -req -days 365000 \
    -in zchd.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
    -extfile <(printf "subjectAltName=DNS:www.example.com,DNS:www.example2.com") \
    -out example.crt

查看证书信息命令:

1
openssl x509 -text -noout -in  server.key