客户端证书的推荐密钥用法

信息安全 tls 证书 公钥基础设施 x.509
2021-08-29 04:29:43

我的程序有以下流程:客户端向服务器发送 CSR,服务器发回客户端证书,然后客户端与服务器通信到需要服务器签名的证书(客户端证书)的路径

我的问题是:

  1. 我在生成的客户端证书中设置了 clientAuth 扩展密钥用法。我应该添加任何其他密钥用法吗?也许是“数字签名”KU?

  2. “数字签名”密钥用法是什么意思?我已经尽可能多地阅读了它,但我仍然不确定它是否适用于我(到目前为止我能找到的最好的信息来源是这个)。

  3. 添加这个key用法的实际意义是什么?(行为良好的 SSL 客户端/服务器会阻止哪些操作?)与不指定任何密钥用法相反?(仅限 clientAuth EKU)

2个回答

TL-DR SSL 客户端证书不需要 KeyUsage,但如果存在,它应该是数字签名,除了非常罕见的固定-*DH。

警告:您标记了 SSL,所以我假设“需要证书的路径”是指 SSL/TLS 或 SSL/TLS 之上的东西(不一定是 HTTP/S)。如果您的意思更像是 CMS 或 S/MIME,或 XML-sig,甚至 PGP,答案可能会有所不同。

我很惊讶您没有找到其他参考资料,因为 X.509 证书被广泛使用。我的谷歌 X.509 密钥使用扩展的第一页给出了PKIX rfc5280,它是当前有效的 Internet 规范及其前身 rfc3280的(文本形式) ;不太好的维基百科文章;https://access.redhat.com/documentation/en-us/red_hat_certificate_system/10/html/administration_guide/standard_x.509_v3_certificate_extensions对包括 SSL 客户端在内的几种情况有(可能过度)特定说明。引用 5280 的相关部分(您的 IBM 站点或多或少地复制了该部分):

   Bits in the KeyUsage type are used as follows:

      The digitalSignature bit is asserted when the subject public key
      is used for verifying digital signatures, other than signatures on
      certificates (bit 5) and CRLs (bit 6), such as those used in an
      entity authentication service, a data origin authentication
      service, and/or an integrity service.

      The nonRepudiation bit is asserted when the subject public key is
      used to verify digital signatures, other than signatures on
      certificates (bit 5) and CRLs (bit 6), used to provide a non-
      repudiation service that protects against the signing entity
      falsely denying some action.  In the case of later conflict, a
      reliable third party may determine the authenticity of the signed
      data.  (Note that recent editions of X.509 have renamed the
      nonRepudiation bit to contentCommitment.)

      The keyEncipherment bit is asserted when the subject public key is
      used for enciphering private or secret keys, i.e., for key
      transport.  For example, this bit shall be set when an RSA public
      key is to be used for encrypting a symmetric content-decryption
      key or an asymmetric private key.

      The dataEncipherment bit is asserted when the subject public key
      is used for directly enciphering raw user data without the use of
      an intermediate symmetric cipher.  Note that the use of this bit
      is extremely uncommon; almost all applications use key transport
      or key agreement to establish a symmetric key.


      The keyAgreement bit is asserted when the subject public key is
      used for key agreement.  For example, when a Diffie-Hellman key is
      to be used for key management, then this bit is set.

      The keyCertSign bit is asserted when the subject public key is
      used for verifying signatures on public key certificates.  If the
      keyCertSign bit is asserted, then the cA bit in the basic
      constraints extension (Section 4.2.1.9) MUST also be asserted.

      The cRLSign bit is asserted when the subject public key is used
      for verifying signatures on certificate revocation lists (e.g.,
      CRLs, delta CRLs, or ARLs).

      The meaning of the encipherOnly bit is undefined in the absence of
      the keyAgreement bit.  When the encipherOnly bit is asserted and
      the keyAgreement bit is also set, the subject public key may be
      used only for enciphering data while performing key agreement.

      The meaning of the decipherOnly bit is undefined in the absence of
      the keyAgreement bit.  When the decipherOnly bit is asserted and
      the keyAgreement bit is also set, the subject public key may be
      used only for deciphering data while performing key agreement.

这必然有点笼统,因为 X.509(和 PKIX)证书被设计用于一系列用途,而不仅仅是 SSL/TLS,尽管这是大多数人知道的唯一用途。它确实区分了几种类型的签名、加密和密钥协议(实际上用于加密)。

5280/3280 只强制 CA 证书使用 KeyUsage,隐含地让 EE 证书可选。我没有实际的 X.509,但 AFAIU 它说如果 KeyUsage 不存在,它被视为所有位设置,因为在有任何扩展之前它与 v1 和 v2 兼容。CABforum 基线明确指定它是 CA 证书的要求,但对于“订阅者”(意为 EE)证书是可选的。

TLSv1.2(或其前身)需要客户端证书“允许...签名”,除了固定 DH 和固定 ECDH 密钥交换,至少在公共网络上似乎没有人使用,相关部分解释了如何除了固定DH 之外,客户端密钥实际上仅用于签署握手数据以证明拥有并因此验证客户端。这意味着如果 SSL 客户端的 KeyUsage 存在,则它必须包含数字签名,并且由于通常在没有充分理由的情况下不应将加密密钥用于多种目的,因此 SSL 客户端的 KeyUsage 不应包含其他任何内容。如果客户端证书没有 KeyUsage 或具有非限制性 KeyUsage,则符合标准的 SSL/TLS 实现仍将仅以协议指定的方式使用该密钥和证书,除了固定 -如前所述,DH 仅对不是证书或 CRL 的数据进行签名/验证。

这是 libNSS 的答案:

对于 Mozilla Firefox 使用的 libNSS,答案隐藏在 ./certdb/certdb.c 中:

实际检查使用情况时:

  case certUsageSSLClient:
    /* 
     * RFC 5280 lists digitalSignature and keyAgreement for
     * id-kp-clientAuth.  NSS does not support the *_fixed_dh and
     * *_fixed_ecdh client certificate types.
     */
    requiredKeyUsage = KU_DIGITAL_SIGNATURE;
    requiredCertType = NS_CERT_TYPE_SSL_CLIENT;

如果未设置 KeyUsage 扩展,则其行为类似于已完全设置:

/* if the extension is not present, then we allow all uses */
cert->keyUsage = KU_ALL;

如果它设置然后,那么,它设置

    if (keyUsage & PKIX_DIGITAL_SIGNATURE){
            nssKeyUsage = nssKeyUsage | KU_DIGITAL_SIGNATURE;
    }

NSS 证书类型应设置 NS_CERT_TYPE_SSL_CLIENT。CertType 派生自 EKU :

如果没有 EKU,则设置 NS_CERT_TYPE_SSL_CLIENT。

/* If no NS Cert Type extension and no EKU extension, then */
nsCertType = 0;
...
/* allow any ssl or email (no ca or object signing. */
nsCertType |= NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
              NS_CERT_TYPE_EMAIL;

如果有 EKU,则 NS_CERT_TYPE_SSL_CLIENT 仅在不是 CA 时设置。

if (findOIDinOIDSeqByTagNum(extKeyUsage,
                SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==
    SECSuccess){
    if (basicConstraintPresent == PR_TRUE &&
    (basicConstraint.isCA)) {
    nsCertType |= NS_CERT_TYPE_SSL_CA;
    } else {
    nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
    }
}

因此,在实践中,libNSS(从2015 年 10 月 25 日的 mercurial 存储库https://hg.mozilla.org/projects/nss获得)是有效的客户端证书,它应该与这些断言之一匹配:

  • EKU 和 KU 未设置。
  • KU 未设置且 EKU 设置为 clientAuth 且证书不是 CA。
  • KU 包含 digitalSignature 并且 EKU 未设置
  • KU 包含 digitalSignature 并且 EKU 设置为 clientAuth 并且 cert 不是 CA。