程序员

初识NSS,一文了解全貌

2018-06-09  本文已影响18人  虞大胆的叽叽喳喳

我写的《深入浅出HTTPS:从原理到实战》这个月快出版了,虽然书写完了,但是我对密码学和SSL的学习却没有停止,从5月份开始我就一直研究(主要是最新的密码学知识、以前没有接触的知识),并且将学习的内容发表在公众号(yudadanwx)和简书中,也就是说我在简书和公众号中所有相关的密码学文章不会和《深入浅出HTTPS:从原理到实战》书中的内容相重合,如果大家有兴趣,还请关注。

欢迎关注我的公众号(yudadanwx),了解我最新的博文。 yudadanwx

本文介绍一个密码学和TLS的实现,这就是 NSS,由 Mozilla 维护,我们熟知的 Firefox 就基于它实现 TLS 协议,另外一个比较引人注目的就是它的可信任CA根证书列表,我全面的浏览了NSS的官方文档,做了一个简单的笔记。

NSS 是什么

NSS 是开源软件,和 OpenSSL 一样,是一个底层密码学库,包括 TLS 实现。NSS 并不是完全由 Mozilla 开发出来的,很多公司(包括 Google)和个人都贡献了代码,只是 Mozilla 提供了一些基础设施(比如代码仓库、bug 跟踪系统、邮件组、讨论组)。

NSS 是跨平台的,很多产品都使用了NSS 密码库,包括:

NSS 支持的密码学算法标准和应用如下:

NSS 提供了完整的软件开发包,包括密码库、API、命令行工具、文档集(API references、man 帮助、示例代码)。NSS 3.14版本开始,升级到 GPL 兼容的 MPL 2.0 许可证。

NSS 符合 FIPS 140(1&2)标准,FIPS 标准是美国政府定义的一种标准,主要是数据编码的标准。NSS 库也通过了 NISCC TLS/SSL 和 S/MIME 的测试(160万输入数据的测试),NISCC 是英国政府提出的安全标准。

在使用 NSS 之前,Mozilla 建议你应该具备一些知识,否则会很晕乎,知识列表如下:

编译 NSS

NSS 最新的版本是 3.37.1,是今年 5 月 22号发布的,由于 NSS 依赖于 NSPR,所以该版本需要的 NSPR 版本必须大于 NSPR 4.19,3.37.1 版本详细信息见release

(1)获取代码

你可以直接下载下载最新版本(包括 nspr),你也可以使用 hg(类似于git)获取最新的开发版本,比如运行下列命令:

$ mkdir nssproject && cd nssproject
$ hg clone https://hg.mozilla.org/projects/nspr
$ hg clone https://hg.mozilla.org/projects/nss

获取的代码分别保存在同级目录下,分别是 nss 和 nspr。在 nss/lib 目录下包含所有导出 api 的源文件,其中 .def 后缀的文件包含对应的 api 列表,比如可以查看 lib/ssl/ssl.def,了解 ssl 协议包含的各种 api。

(2)编译

编译过程还是比较麻烦的,因为 nss 不使用 configure 脚本,所以需要配置不同的环境变量,比如在 linux 使用 shell,在 windows 上使用 Mozilla 提供的构建包。

以下介绍在 Ubuntu(Ubuntu 14.04.5 LTS/x86_64,如果不知道查看操作系统版本和该系统是32位还是64位,可以使用 lsb_release -a 和 uname -a 命令行)下的编译过程:

$ BUILD_OPT=1
$ USE_64=1 
$ export BUILD_OPT
$ export USE_64

$ cd nss
$ make nss_build_all

编译完成后,所有编译的文件全部保存在 dist 目录下(和 nss 目录同级),其中最主要的目录是 Linux3.13_x86_64_cc_glibc_PTH_64_OPT.OBJ#,这是根据操作系统动态命名的一个目录,包含了三个子目录:

如果你编译的时候遇到问题,可以参考additional information of interest

如果你想做一些开发工作,你可以运行脚本进行测试,比如运行下列命令:

# 测试 all.sh
$ cd nss/tests
$ ./all.sh 

# 测试单个 sh
$ cd nss/tests/cert
$ ./cert.sh

测试的结果在 nssproject/tests_results 目录下,如果你想掌握命令行的使用,应该好好阅读 all.sh 文件的内容。

关于 NSS API

对于我来说,主要想法是根据 NSS API 手册使用库对应的功能(比如加密解密),但是了解代码的组织方式还是非常有必要的,我简单看了遍相关内容。

NSS 代码是分层(Layer)的,分为底层 API 和高层 API,底层 API 完成特定的工作,它不能调用上层的高层 API,而高层 API 主要是包装底层 API,然后给开发者调用。

分层结构如下图:

2018-06-09-nss-nsslapiayer.gif

NSS API 对外的就是包,包包括一些头文件、包文件等信息,列举几个例子:

Library 描述 Layer 目录 头文件
certdb 证书处理 Low Cert lib/certdb cdbhdl.h 等
pkcs 12 PKCS #12 数据处理 PKCS #12 lib/pkcs12 pkcs12t.h 等

NSS 服务提供静态库和动态库,开发者如果想使用静态库,那么只能调用开发者导出的 API,而且这些 API 都能和新版本兼容。

不同的操作系统,NSS 的静态库和动态库有不同的命名约定,见下列表格:

库类型 Windows Unix
静态库 .lib .a
动态库 .dll .so 或者 .sl

NSS 整个架构图如下:

2018-06-09-nss-nsslayer.gif

API 的概要说明见NSS Public Functions,API 详细的调用说明见NSS Reference

NSS API 都是 C 语言调用的(NSS 本身也是 C 语言开发的),我个人对 Python 比较熟悉,可以使用 python-nss 模块进行开发,后续也会介绍一下。

NSS 命令行工具

NSS 编译后,除了包,还包含很多命令行工具,不过这些工具的功能和 OpenSSL 还没发比,关于工具使用,可以参考NSS Security Tools

编译后,直接运行命令行会报错的,需要 export 一些目录,比如运行下列的命令:

$ export LD_LIBRARY_PATH='/root/nssproject/dist/Linux3.13_x86_64_cc_glibc_PTH_64_OPT.OBJ/lib:'
$ nssproject/dist/Linux3.13_x86_64_cc_glibc_PTH_64_OPT.OBJ/bin/certutil

那么如果不编译 nss,如何使用这些命令行工具呢?在各个发行版中其实都有专门的安装包,比如在 Ubuntu 下安装 libnss3-tools 工具:

$ apt-get install libnss3-tools 

需要指出的是 Mozilla NSS 最让人知晓的是可信任根证书列表(关于其后面还会专门写博文介绍,包括 Curl 命令行工具如何使用 NSS 的根证书列表),但是在编译 NSS 的时候,并没有发现根证书列表文件(后续再研究下),不过可以使用 certutil 创建和管理证书,包括导入到可信任根证书文件中。

The Certificate Database Tool is a command-line utility that can create and modify the Netscape > Communicator cert8.db and key3.db database files. It can also list, generate, modify, or delete > certificates within the cert8.db file and create or change the password, generate new public
and private key pairs, display the contents of the key database

接下去介绍简单的用法:

生成新的 cert 文件:

$ export LD_LIBRARY_PATH='/root/nssproject/dist/Linux3.13_x86_64_cc_glibc_PTH_64_OPT.OBJ/lib:'
$ mkdir /root/nssdbnew
$ bin/certutil -L -d /root/nssdbnew

在 /root/nssdbnew 目录下会生成三个文件,分别是 cert9.db、key4.db、pkcs11.txt,如果使用系统的 certutil(libnss3-tools 包安装的)运行,生成的文件是 cer8.db。

然后生成一个 CSR 文件(证书申请请求):

$ bin/certutil -R -s "CN=John Smith, O=Netscape, L=Mountain View, ST=California, C=US" -p "650-555-8888" -o mycert.req -d /root/nssdbnew/ 

奇怪的是,要不停的按回车键和空格键才能最终运行完成,生成的 csr 文件就是 mycert.req 。

接下去根据 csr 文件生成证书文件:

$ certutil -S -s "CN=My Issuer" -n myissuer -x -t "C,C,C" -1 -2 -5 -m 1234  -d /root/nssdbnew/
$ certutil -C -m 2345 -i mycert.req -o mycert.crt -c myissuer -d  /root/nssdbnew/

不过最后一直卡着,到最后也没完成(相比 OpenSSL 还得加把劲啊)。

最后我将自己网站的一个证书加入到 cert9.db 中,命令如下:

$ certutil -A -n ywdblog@outlook.com -t "p,p,p" -i cert.pem  -d /root/nssdbnew    
$ certutil -L -n ywdblog@outlook.com -d /root/nssdbnew         

以上两个命令是将一个证书加入到根证书列表文件中,然后再从 cert9.db 文件中读取相应的证书。

关于 NSS 其实还有很多内容,后续想分享以下一些内容:

上一篇 下一篇

猜你喜欢

热点阅读