DEV Community

Michael
Michael

Posted on

1

Ubuntu上默认证书库是怎么回事

背景

最近整HTTP3客户端时候,需要验证服务端证书,中间出了点小插曲,老是报错见上篇文章,问题解决了但是想到另外个问题,浏览器和客户端都是怎么验证证书的,我们都知道服务端给出证书,客户端根据本地的或者用户提供的根证书校验,但是系统根证书在哪儿,为什么我没有设置,他们就自动找到了?本文旨在根据这个问题,梳理Ubuntu系统自带证书库和浏览器的证书库。本文主要聚焦Ubuntu系统,但是其他系统的流程大致相似。

系统证书库

Ubuntu系统的证书目录位于/etc/ssl/certs, 根证书是/etc/ssl/certs/ca-certificates.crt。 其他平台的默认证书可以查看golang源码文件

查看/etc/ssl/certs发现里面有很多pem格式证书,这里就是系统根证书目录,我的机器上面有部分软链接到/usr/share/ca-certificates/mozilla(这个是系统读取/etc/ca-certificates.conf配置加入的)。文件/etc/ssl/certs/ca-certificates.crt是这些证书的合集,可以使用如下命令查看所有证书的subject

awk -v cmd='openssl x509 -noout -subject' '/BEGIN/ {close(cmd)}; {print | cmd}' < /etc/ssl/certs/ca-certificates.crt
Enter fullscreen mode Exit fullscreen mode

系统证书更新

系统不建议我们自己手动证书到这个目录和文件中,那我们如何添加证书到系统呢?系统提供了命令update-ca-certificates

man 8 update-ca-certificates
Enter fullscreen mode Exit fullscreen mode

根据manpage介绍,update-ca-certificates更新etc/ssl/certsca-certificates.crt。我们将pem格式证书以.crt后缀放到/usr/local/share/ca-certificates,一个证书一个文件,然后执行命令就会自动添加到根目录证书中。

寻找证书

刚才不建议咱们自己添加证书,因为其中有些步骤是看不见的,比如c_rehash过程。寻找证书通过证书的subject,如果通过打开文件找到subject比对,那这样效率太低了,所以通过将证书的subject的hash值作为文件名,就可以提高寻找效率了,rehash就是干这个事。比如,我的系统中有个Go_Daddy_Class_2_CA.pem证书

ll /etc/ssl/certs | grep 'Go_Daddy_Class_2_CA'
# f081611a.0 -> Go_Daddy_Class_2_CA.pem 这个是rehash生成文件
# Go_Daddy_Class_2_CA.pem -> /usr/share/ca-certificates/mozilla/Go_Daddy_Class_2_CA.crt
Enter fullscreen mode Exit fullscreen mode

可以通过以下命令看下hash值是否正确(当然是正确的)

openssl x509 -hash -fingerprint -noout -in $(readlink -f /etc/ssl/certs/Go_Daddy_Class_2_CA.pem)
# f081611a
# SHA1 Fingerprint=27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4
Enter fullscreen mode Exit fullscreen mode

最后的.0是为了防止hash碰撞产生一样的值。

OpenSSL

OpenSSL默认情况使用系统证书库

openssl version -d # 打印OpenSSL目录
ls -l $(openssl version -d | tr -d '"' | awk '{print $2}') # 查看OpenSSL目录内容
Enter fullscreen mode Exit fullscreen mode

通过查看OpenSSL目录,里面的certs文件夹默认是软链接到/etc/ssl/certs。因此OpenSSL编写代码使用默认证书库就是系统证书库

SSL_CTX_set_default_verify_paths(ssl_ctx);
Enter fullscreen mode Exit fullscreen mode

浏览器

浏览器一般使用图形界面设置,但是我就觉得纳闷了,我在浏览器中设置了,但是根目录证书中没有,猜想肯定使用自己证书库,查找后确定是这样的。

FirefoxChrome都使用sqlite存储用户导入证书,具体放在文件cert9.db中,早期放在cert8.db,这里咱们不溯源历史,有兴趣可以查看相关文档。同样,这个数据库不建议直接操作,浏览器都使用了NSS_Shared_DB管理数据库,提供了命令certutil操作,Ubuntu需要安装libnss3-tools

sudo apt install libnss3-tools
Enter fullscreen mode Exit fullscreen mode

Chromium源码文档中有提供如何操作。

查找浏览器证书库地址

命令操作没啥问题,但是关键是制定证书的数据库地址。Ubuntu一般使用snap(尽管不想使用)按照Chrome,会放在snap目录$HOME/snap/[chromium|firefox],如果没有snap目录,可以查看个人目录隐藏文件夹$HOME/.pki/nssdb,可能会不一样,可以通过查找方式查询:

find $HOME -type f -name 'cert9.db'
Enter fullscreen mode Exit fullscreen mode

注意浏览器都是以用户(profile)形式生成cert9.db的,Chromium系列明显亲民点,可以使用比如$HOME/snap/chromium/current软链接到当前用户目录。

JKS(Java Key Store)

在前面查看/etc/ssl/certs目录时,看到有个文件夹java,翻看资料后发现,JAVA平台可以使用自己的证书库,支持多种存储格式,JKS的store位于$JAVA_HOME/lib/security/cacerts或者$JAVA_HOME/jre/lib/security/cacerts,JKS使用JDK提供的工具keytool管理。JKS的store默认密码是changeit

# find JAVA_HOME
export JAVA_HOME=readlink -f $(which java) | sed 's/\/bin\/java//'

# List
keytool -list -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit | head -5
# OR
keytool -list -cacerts -storepass changeit | head -5

# Add
keytook -import -alias testCert -keystore $JAVA_HOME/lib/security/cacerts -file ca_cert.crt
Enter fullscreen mode Exit fullscreen mode

有用知识

工具mkcert是cert操作相关的库,里面有上面的相关信息,有兴趣可以仔细查看阅读。

Image of Docusign

Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay