第 4 章 通过PKCS #11配置应用程序以使用加密硬件。

在专用加密设备上分离部分秘密信息,如用于终端用户认证的智能卡和加密令牌,以及用于服务器应用的硬件安全模块(HSM),可提供额外的安全层。在Red Hat Enterprise Linux 8中,通过PKCS #11 API对加密硬件的支持在不同的应用中是一致的,在加密硬件上隔离秘密并不是一件复杂的事情。

4.1. 通过PKCS #11提供加密硬件支持。

PKCS #11(公钥密码学标准)定义了一个应用编程接口(API),用于存放密码信息和执行密码功能的密码设备。这些设备被称为代币,它们可以以硬件或软件的形式实现。

一个PKCS #11令牌可以存储各种对象类型,包括证书;数据对象;以及公钥、私钥或秘钥。这些对象是通过PKCS #11 URI方案来唯一识别的。

PKCS #11 URI是根据对象属性识别PKCS #11模块中特定对象的标准方式。这使得你可以用URI形式的配置字符串配置所有的库和应用程序。

Red Hat Enterprise Linux 8默认为智能卡提供OpenSC PKCS #11驱动程序。然而,硬件令牌和HSM可以拥有自己的PKCS #11模块,而这些模块在Red Hat Enterprise Linux中没有对应的模块。你可以用p11-kit工具注册这样的PKCS #11模块,它在系统中注册的智能卡驱动程序上起着包装的作用。

要使自己的PKCS #11模块在系统中工作,请在/etc/pkcs11/modules/目录中添加一个新的文本文件。

你可以在/etc/pkcs11/modules/目录下新建一个文本文件,将自己的PKCS #11模块添加到系统中。例如,p11-kit中的OpenSC配置文件如下。

$ cat /usr/share/p11-kit/modules/opensc.module
module: opensc-pkcs11.so

4.2. 使用保存在智能卡中的 SSH 密钥

Red Hat Enterprise Linux 8 可让您使用保存在 OpenSSH 客户端智能卡中的 RSA 和 ECDSA 密钥。使用这个步骤使用智能卡而不是使用密码启用验证。

先决条件

  • 在客户端中安装了 opensc 软件包,pcscd 服务正在运行。

流程

  1. 列出所有由 OpenSC PKCS #11 模块提供的密钥,包括其 PKCS #11 URIs,并将输出保存到 key.pub 文件:

    $ ssh-keygen -D pkcs11: > keys.pub
    $ ssh-keygen -D pkcs11:
    ssh-rsa AAAAB3NzaC1yc2E...KKZMzcQZzx pkcs11:id=%02;object=SIGN%20pubkey;token=SSH%20key;manufacturer=piv_II?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so
    ecdsa-sha2-nistp256 AAA...J0hkYnnsM= pkcs11:id=%01;object=PIV%20AUTH%20pubkey;token=SSH%20key;manufacturer=piv_II?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so
  2. 要使用远程服务器上的智能卡(example.com)启用验证,将公钥传送到远程服务器。使用带有上一步中创建的 key.pubssh-copy-id 命令:

    $ ssh-copy-id -f -i keys.pub username@example.com
  3. 要使用在第 1 步的 ssh-keygen -D 命令输出中的 ECDSA 密钥连接到 example.com,您只能使用 URI 中的一个子集,它是您的密钥的唯一参考,例如:

    $ ssh -i "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so" example.com
    Enter PIN for 'SSH key':
    [example.com] $
  4. 您可以使用 ~/.ssh/config 文件中的同一 URI 字符串使配置持久:

    $ cat ~/.ssh/config
    IdentityFile "pkcs11:id=%01?module-path=/usr/lib64/pkcs11/opensc-pkcs11.so"
    $ ssh example.com
    Enter PIN for 'SSH key':
    [example.com] $

    因为OpenSSH使用p11-kit-proxy包装器,且OpenSC PKCS #11模块注册在PKCS#11 Kit上,所以可以简化前面的命令。

    $ ssh -i "pkcs11:id=%01" example.com
    Enter PIN for 'SSH key':
    [example.com] $

如果您跳过 PKCS #11 URI 的 id= 部分,则 OpenSSH 会加载代理模块中可用的所有密钥。这可减少输入所需的数量:

$ ssh -i pkcs11: example.com
Enter PIN for 'SSH key':
[example.com] $

其它资源

4.3. 在Apache和Nginx中使用HSM保护私钥。

ApacheNginxHTTP服务器可以使用存储在硬件安全模块(HSM)上的私钥工作,这有助于防止密钥泄露和中间人攻击。请注意,这通常需要为繁忙的服务器提供高性能的HSM。

ApacheHTTP服务器

对于HTTPS协议形式的安全通信,ApacheHTTP服务器(httpd)使用了OpenSSL库。OpenSSL不支持PKCS #11。要利用HSMs,你必须安装openssl-pkcs11包,该包通过引擎接口提供对PKCS #11模块的访问。您可以使用 PKCS #11 URI 而不是常规文件名在 /etc/httpd/conf.d/ssl.conf 配置文件中指定服务器密钥和证书,例如:

SSLCertificateFile    "pkcs11:id=%01;token=softhsm;type=cert"
SSLCertificateKeyFile "pkcs11:id=%01;token=softhsm;type=private?pin-value=111111"

安装httpd-manual包以获得ApacheHTTP服务器的完整文档,包括TLS配置。/etc/httpd/conf.d/ssl.conf 配置文件中的指令在 /usr/share/httpd/manual/mod_ssl.html 中有详细介绍。

NginxHTTP和代理服务器

因为Nginx也使用OpenSSL进行加密操作,所以对PKCS #11的支持必须通过openssl-pkcs11引擎。Nginx目前只支持从HSM加载私钥,证书必须作为常规文件单独提供。修改/etc/nginx/nginx.conf配置文件中服务器部分的ssl_certificatessl_certificate_key选项。

ssl_certificate     /path/to/cert.pem
ssl_certificate_key "engine:pkcs11:pkcs11:token=softhsm;id=%01;type=private?pin-value=111111";

请注意,Nginx配置文件中的PKCS #11 URI需要引擎:pkcs11:前缀。这是因为另一个pkcs11前缀指的是引擎名称。

4.4. 配置应用程序使用智能卡中的证书进行认证。

  • wget网络下载器可以让您指定 PKCS #11 URI,而不是本地存储的私钥的路径,从而简化了为需要安全存储私钥和证书的任务创建脚本。例如:

    $ wget --private-key 'pkcs11:token=softhsm;id=%01;type=private?pin-value=111111' --certificate 'pkcs11:token=softhsm;id=%01;type=cert' https://example.com/

    更多信息请参见wget(1)man 页面。

  • 指定pkcs #11 URI供curl工具使用是类似的。

    $ curl --key 'pkcs11:token=softhsm;id=%01;type=private?pin-value=111111' --cert 'pkcs11:token=softhsm;id=%01;type=cert' https://example.com/

    更多信息请参见curl(1)man 页面。

  • 火狐浏览器会自动加载p11-kit-proxy模块。这意味着,系统中每一张支持的智能卡都会被自动检测到。对于使用TLS客户端认证,不需要额外的设置,当服务器请求时,会自动使用智能卡中的密钥。

在自定义应用程序中使用PKCS #11 URIs

如果你的应用程序使用GnuTLSNSS库,对PKCS #11 URI的支持由它们内置的PKCS #11支持来保证。同时,由于openssl-pkcs11引擎的存在,依赖OpenSSL库的应用程序可以访问加密硬件模块。

对于需要在智能卡上使用私钥,且不使用NSSGnuTLSOpenSSL的应用,使用p11-kit来实现注册PKCS #11模块。

更多信息请参见p11-kit(8)man 页面。


为了尽快向用户提供最新的信息,本文档可能会包括由机器自动从英文原文翻译的内容。如需更多信息,请参阅此说明。