web-dev-qa-db-fra.com

Utilisation de clé recommandée pour un certificat client

Mon programme a le flux suivant: un client envoie une CSR au serveur, le serveur renvoie un certificat client et après cela le client communique avec le serveur vers un chemin qui nécessite un certificat signé par le serveur (le certificat client)

Mes questions sont:

  1. J'ai défini l'utilisation de la clé étendue clientAuth dans le certificat client généré. Dois-je ajouter des utilisations clés supplémentaires? Peut-être "digitalSignature" KU?

  2. Que signifie l'utilisation de la clé "digitalSignature"? J'en ai lu autant que possible, mais je ne sais toujours pas si cela s'applique à moi (la meilleure source d'informations que j'ai pu trouver jusqu'à présent était this ).

  3. Quelle est la signification pratique de l'ajout de cette utilisation clé? (quelles actions seront empêchées par des clients/serveurs SSL bien comportés?) Au lieu de ne spécifier aucun usage clé? (uniquement le clientAuth EKU)

12
yair

TL-DR Le certificat client SSL n'a pas besoin de KeyUsage mais s'il est présent, il doit être digitalSignature sauf pour très rare, voire jamais fixe- * DH.

Mise en garde: Vous avez marqué SSL, donc je suppose que par "chemin qui nécessite un certificat", vous voulez dire SSL/TLS ou quelque chose sur SSL/TLS (pas nécessairement HTTP/S). Si vous voulez dire quelque chose de plus comme CMS ou S/MIME, ou XML-sig, ou même PGP, la réponse peut être différente.

Je suis surpris que vous ne trouviez pas d'autres références car les certificats X.509 sont si largement utilisés. Ma première page de l'extension d'utilisation de la clé google X.509 donne PKIX rfc528 qui est la spécification Internet actuellement en vigueur et (la forme texte de) son prédécesseur rfc328 ; l'article wikipedia pas terriblement bon; et https://access.redhat.com/documentation/en-US/Red_Hat_Certificate_System/8.0/html/Admin_Guide/Standard_X.509_v3_Certificate_Extensions.html qui a (éventuellement) des instructions spécifiques pour plusieurs cas, y compris Client SSL. Citant la partie pertinente du 5280 (que votre site IBM copie plus ou moins):

   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.

C'est nécessairement quelque peu général car les certificats X.509 (et PKIX) ont été conçus pour être utilisés pour une variété de choses, pas seulement SSL/TLS, bien que ce soit le seul usage que la plupart des gens connaissent. Il distingue plusieurs types de signature, de chiffrement et d'accord de clé (qui, en pratique, sont utilisés pour le chiffrement).

5280/3280 n'impose que KeyUsage pour les certificats CA, le laissant implicitement facultatif pour les certificats EE. Je n'ai pas de X.509 réel mais AFAIU il dit que si KeyUsage n'est pas présent, il est traité comme tous les bits définis, car cela est compatible avec v1 et v2 avant qu'il n'y ait des extensions. CABforum baseline le spécifie explicitement comme requis pour les certificats CA mais facultatif pour les certificats "abonné" (c'est-à-dire EE).

TLSv1.2 (ou ses prédécesseurs) nécessite un certificat client "autorise ... la signature" à l'exception des échanges de clés fixed-DH et fixed-ECDH que personne ne semble utiliser au moins sur le public net, et les sections connexes expliquent comment, à l'exception de fixed- * DH, la clé client n'est en fait utilisée que pour signer des données de prise de contact pour prouver la possession et donc authentifier le client. Cela signifie que si KeyUsage est présent pour le client SSL, il doit inclure digitalSignature, et comme en général une clé de chiffrement ne doit pas être utilisée à des fins multiples sans justification solide, KeyUsage pour client SSL ne doit rien inclure d'autre. Si le certificat client n'a pas KeyUsage ou a un KeyUsage non restrictif, une implémentation SSL/TLS conforme utilisera toujours cette clé et cert uniquement de la manière spécifiée par le protocole, qui, à l'exception de fixed- * DH comme indiqué, ne fait que signer/vérifier les données qui ne sont pas un certificat ou une liste de révocation de certificats.

12
dave_thompson_085

Voici une réponse pour libNSS:

Pour libNSS utilisé par Mozilla Firefox, la réponse est cachée dans ./certdb/certdb.c:

Lors de la vérification réelle de l'utilisation:

  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;

si l'extension KeyUsage n'est pas définie, elle se comporte comme si elle était entièrement définie:

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

si elle est définie, eh bien, elle est définie

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

Le type de certificat NSS doit avoir NS_CERT_TYPE_SSL_CLIENT défini. CertType est dérivé d'EKU:

si aucun EKU, NS_CERT_TYPE_SSL_CLIENT est défini.

/* 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;

S'il existe des EKU, NS_CERT_TYPE_SSL_CLIENT est défini UNIQUEMENT s'il ne s'agit pas d'une autorité de certification.

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;
    }
}

Donc, en pratique, libNSS (comme obtenu depuis le référentiel Mercurial https://hg.mozilla.org/projects/nss le 25 octobre 2015) pour être un certificat client valide, il doit correspondre à l'une de ces affirmations:

  • EKU ET KU ne sont PAS définis.
  • KU n'est pas défini ET EKU est défini sur clientAuth ET cert n'est PAS une autorité de certification.
  • KU contient digitalSignature ET EKU n'est PAS défini
  • KU contient digitalSignature ET EKU est défini sur clientAuth ET cert n'est PAS une AC.
7
philippe lhardy