En cryptographie, la fonction de hachage (ou calcul de condensé) est essentielle. Une de ses applications est la génération de signatures selon le schéma hash and sign, et bien sûr leur vérification, ou encore le calcul de codes d'authentification de messages (MAC). La fonction de hachage est à sens unique, mais surtout, elle doit être résistante aux collisions. Vous trouverez des informations didacticielles et pas trop indigestes (pun intended J) sur le sujet chez Mironov.

On a assez longtemps utilisé MD5 (Message Digest - 128 bits) qui aujourd'hui (et même depuis plusieurs années – 1996?) est à bannir définitivement (voir http://blogs.technet.com/pascals/archive/2008/12/31/collisions-md5-et-vrais-faux-certificats.aspx). Son successeur, SHA-1 (Secure Hash Algorithm - 160 bits) est aussi suspecté d'être sujet à collisions et déjà considéré comme un peu short pour la signature électronique. Selon NIST (National Institute of Standards and Technology) : "Federal agencies should stop using SHA-1 for digital signatures, digital time stamping and other applications that require collision resistance as soon as practical" (voir aussi http://www.rsa.com/rsalabs/node.asp?id=2834 ou encore RFC 4270).

Les collisions permettent en théorie de forger une signature, ou plutôt de créer un deuxième document (appelons-le « faux » document) pour lequel la signature générée sur un premier document (« vrai » document) est valide car les deux documents produisent le même condensé. L'attaque dite de « seconde pré-image » qui consiste à trouver un faux document, qui plus est « utile », pour un premier document imposé est bien plus difficile que l'attaque de collision de base (paradoxe des anniversaires), pour laquelle l'attaquant peut choisir les deux documents, avant de faire signer le vrai document par la victime. Un certificat étant un document signé suite à une requête de certification, on conçoit comment il est possible de créer de faux certificats par une attaque de collision.

L'attaque de collision MD5 aujourd'hui praticable sur les seuls certificats MD5 s'apparente à une attaque pour laquelle l'attaquant choisit le vrai et le faux document. Cependant, pas mal de contraintes subsistent pour l'attaquant : la structure de la partie du certificat à faire signer par la CA est imposée, et seule une partie de son contenu est relativement libre. De plus, il est nécessaire pour l'attaquant de prédire les numéros de série et date de validité qui seront affectés au vrai certificat par l'autorité de certification (on peut raisonnablement penser qu'on retrouvera ce type de contraintes dans beaucoup d'attaques de collision car il faut que la victime accepte de son plein gré de signer le vrai document). A noter aussi que le faux certificat doit comporter les bits nécessaires à la collision, ce qui constitue une véritable « verrue » à dissimuler et qui pourrait éventuellement mettre la puce à l'oreille de l'utilisateur (très bien averti), et du moins être détectée lors d'une investigation.

Il faut évidemment arrêter de générer des certificats MD5, et dans l'idéal, il faut arrêter de les utiliser et de leur accorder confiance. Plus facile à dire qu'à faire dans certains cas mais guidelines et recommandations existent.

La publication FIPS 180-2 du NIST a standardisé dès 2002 les condensés dits SHA-2 de longueur 256, 384, et 512 bits (ces trois variantes sont dénommées SHA-256, SHA-384, et SHA-512). Seuls SHA-256 et SHA-512 sont réellement différents en ce sens que les calculs se font sur des entités 32 et 64 bits, ou encore des tailles de blocks 512 et 1024, respectivement, et SHA-384 n'est qu'une version de SHA-512 au résultat tronqué. SHA-2 fait maintenant partie de Suite-B, qui est le standard NSA spécifiant les suites d'algorithmes cryptographiques à utiliser pour la sécurité des systèmes d'information du gouvernement US. Dans la course contre les cryptanalystes, NIST ne perd pas de temps et a déjà lancé le concours pour « SHA-3 ».

Pour un développeur de fonctions de sécurité mettant en jeu la signature et les certificats, ou n'importe quel mécanisme de sécurité nécessitant la résistance aux collisions, l'adoption de SHA-2 est désormais un must, et il apporte en plus la conformité avec Suite-B. Mais comment choisir entre SHA-256 et SHA-512 ? En termes de sécurité, SHA-512 fournira en théorie plus de marge, si tant est qu'on en ait besoin. SHA-256 est censé fournir 128 bits de sécurité contre les attaques de collision, et SHA-512, 256 bits. Néanmoins, différentes applications ou protocoles présentent chacun leurs contraintes, et un niveau de sécurité de « seulement » 128 bits est pour l'instant réputé sûr pour beaucoup d'applications selon les préconisations de la DCSSI (voir aussi www.keylength.com).

La fonction de hachage est souvent utilisée conjointement avec du chiffrement. En termes de cohérence, on pourra utiliser SHA-256 avec AES 128 bits, et on préférera SHA-512 avec AES 256 bits. En termes de taille de messages pour le stockage ou la transmission, SHA-512 représente un coût fixe deux fois plus important que SHA-256, qui peut être impraticable pour un grand nombre de petits messages. Finalement, en termes de performance, SHA-512 est ciblé pour les systèmes 64 bits, et logiquement plus lent que SHA-256 sur les systèmes 32 bits (ce qui en principe n'est pas le cas sur un système 64 bits).

SHA-2 a été disponible de la part de Microsoft sur la plateforme Windows dès le .Net Framework 1.0 avec les classes en code managé, puis plus tard en code natif sur Windows Server 2003 SP1 avec CryptoAPI, et sur Windows Vista et Windows Server 2008 avec CNG (Crypto Next Generation) et CryptoAPI, et finalement sur Windows XP SP3 avec CryptoAPI.

Pour résumer :

API

Disponibilité de SHA2 au niveau de l'API

Classes .Net

A partir du .Net Framework 1.0:
SHA256Managed
, SHA384Managed, SHA512Managed

 

A partir du .Net Framework 3.5 sur Windows Vista:
SHA256Cng
, SHA384Cng, SHA512Cng

 

A partir du .Net Framework 3.5 sur Windows Server 2003 SP1, Windows Vista et Windows XP SP3:

SHA256CryptoServiceProvider, SHA384CryptoServiceProvider, SHA512CryptoServiceProvider

 

Le support de HMAC-SHA2 existe sur le .Net Framework en code managé depuis sa version 2.0 (HMACSHA256, HMACSHA384, HMACSHA512).

 

A noter aussi le wrapper CNG du projet « CLR Security » :

Security.Cryptography.HMACSHA256Cng, Security.Cryptography.HMACSHA384Cng, Security.Cryptography.HMACSHA512Cng.

 

Signature RSA avec SHA-2 disponible récemment (.Net Framework 3.5 SP1) avec RSACryptoServiceProvider. Puisque la classe est un wrapper CryptoAPI, il faut en plus que la plateforme supporte SHA-2 au niveau CryptoAPI (et donc au minimum Windows Server 2003 SP1, Windows Vista, ou Windows XP SP3). On notera à ce sujet l'initiative http://www.codeplex.com/CryptoExtension.

 

Signature ECDSA avec SHA-2 via ECDSACng à partir du .Net Framework 3.5 et Windows Vista. La signature DSA est limitée à SHA-1 (DSA 1024 - DSACryptoServiceProvider).

 

La fonctionnalité n'a pas encore été « remontée » à la signature XML.

CNG

A partir de Windows Vista
BCRYPT_SHA256_ALGORITHM ("SHA256"), BCRYPT_SHA384_ALGORITHM ("SHA384"), BCRYPT_SHA512_ALGORITHM("SHA512")

 

Pour HMAC-SHA2, utiliser le flag BCRYPT_ALG_HANDLE_HMAC_FLAG lors de la connexion au provider d'algorithme.

 

Signature RSA et ECDSA avec SHA-2. La signature DSA est limitée à SHA-1 (DSA 1024).

CryptoAPI

A partir de Windows Server 2003 SP1, ensuite Windows Vista, puis Windows XP SP3
AlgIDs CALG_SHA_256, CALG_SHA_384, CALG_SHA_512

Support via Microsoft Enhanced RSA and AES Cryptographic Provider, et Microsoft Base Smart Card Crypto Provider, si présent. Binaire rsaenh.dll.

 

Pour HMAC-SHA2, utiliser CALG_HMAC, puis CryptSetHashParam:

CryptCreateHash (CALG_HMAC)

CryptSetHashParam (HMAC_INFO. HashAlgid = CALG_SHA_256)

 

Signature RSA avec SHA-2. La signature DSA est limitée à SHA-1 (DSA 1024).

 

On ne répétera jamais assez aux développeurs d'éviter d'utiliser, lorsque possible, les primitives cryptographiques pour bâtir eux-mêmes les protocoles ou fonctions de plus haut niveau dont ils ont besoin. Les vulnérabilités se trouvent dans le protocole, ou l'application, rarement dans l'algorithme crypto en tant que primitive. Mironov cite pour exemple la construction naïve d'un MAC en tant que SHA(secret||message) plutôt que l'utilisation du standard HMAC-SHA (RFC 4868).

Que ce soit pour la génération d'une signature électronique, la dérivation d'une clé à partir d'un mot de passe, ou encore un code d'authentification, une utilisation naïve des primitives peut rapidement conduire au désastre, et on se reportera sur les APIs qui implémentent les méthodes standard, éprouvées, et approuvées par les agences de sécurité tels que HMAC-SHA, RSA, DSA, ECDSA, PBKDF2, etc.

A noter sur Windows 7 la nouvelle API CNG BCryptDeriveKeyPBKDF2 pour la dérivation de clé à partir d'un mot de passe selon RFC 2898 (PKCS#5), qui peut être utilisée avec SHA-2 si on le souhaite. Néanmoins, il est couramment admis que SHA-1 est largement suffisant pour ce scenario.

Windows 7 apporte aussi une nouvelle API native supportant la signature XML RSA et ECDSA avec SHA-2 (API CryptXML… - cryptxml.dll).

Qu'en est-il de PKIX ?

CAPI2 (crypt32.dll) désigne l'API Windows qui met en œuvre le X.509 et le CMS/PKCS#7 (Cryptographic Message Syntax). A partir de Windows Vista et Windows Server 2008, CAPI2 a été capable de prendre en charge les certificats SHA-2 (accessoirement, CAPI2 a aussi été porté sur CNG pour la prise en charge des courbes elliptiques). Une application est donc à même de vérifier une chaîne de certificats X.509 RSA et ECC à base de SHA-2 avec les API CertGetCertificateChain et CertVerifyRevocation. De même, les services de certificats ADCS (Active Directory Certificate Services) de Windows Server 2008 supportent l'émission de certificats SHA-2 RSA et ECC. Finalement, SHA-2 est supporté pour CMS. A ce titre on notera le draft http://www.ietf.org/internet-drafts/draft-ietf-smime-sha2-11.txt sur l'utilisation de SHA-2 avec CMS qui est censé mettre à jour RFC 3370. La mise en œuvre de S/MIME par Office Outlook 2007 (et le contrôle Outlook Web Access d'Exchange 2007) en tire parti, mais pas Windows Mail, ni Windows Live Mail. A noter que SHA-2 est supporté pour la signature, mais la dérivation de la KEK (Key Encryption Key) pour le chiffrement suite à l'accord ECDH utilise encore SHA-1 (dhSinglePass-stdDH-sha1kdf-scheme – voir RFC 3278). Windows 7 apporte le support de dhSinglePass-stdDH-sha256kdf-scheme et dhSinglePass-stdDH-sha384kdf-scheme selon RFC 5008 (comme évoqué plus haut, je ne pense pas que SHA-2 soit totalement indispensable pour la dérivation).

Sur Windows Server 2003 SP1 et SP2, le correctif 938397 APPLICATIONS THAT USE THE CRYPTOGRAPHY API CANNOT VALIDATE AN X.509 CERTIFICATE IN WINDOWS SERVER 2003 (http://support.microsoft.com/kb/938397) amène le support de SHA-2 au niveau CAPI2 de façon à pouvoir vérifier une chaîne comprenant des certificats RSA à base de SHA-2. Cependant Certificate Services de Windows Server 2003 ne peut pas générer de certificats SHA-2, et SHA-2 n'est pas disponible pour CMS.

Sur Windows XP, c'est le SP3 qui amène le support de SHA-2 pour CAPI2, et donc la possibilité de d'utiliser des certificats RSA avec SHA-2, avec IE7 par exemple. Comme pour Windows Server 2003, SHA-2 n'est pas disponible pour CMS.

Le tableau suivant synthétise le support de SHA-2 sur la plateforme:

 

Windows XP

Windows Server 2003

Windows Vista

Windows Server 2008

CryptoAPI

SP3

SP1

RTM

RTM

CNG

--

--

RTM

RTM

Validation de certificats avec CAPI2

SP3

SP1 ou SP2 + KB938397

RTM

RTM

CMS avec CAPI2

Non

Non

RTM

RTM

Emission de certificats avec Certificate Services

--

Non

--

Oui - ADCS

 

Alors bon SHA-2, et merci à Philippe Beraud qui m'a transmis certaines de ces informations…