web-dev-qa-db-fra.com

Leçons apprises et idées fausses concernant le chiffrement et la cryptologie

La cryptologie est un sujet tellement vaste que même les codeurs expérimentés commettront presque toujours des erreurs les premières fois. Cependant, le cryptage est un sujet si important, souvent nous ne pouvons pas nous permettre d'avoir ces erreurs.

Le but de cette question est d'identifier et de lister ce que pas à faire avec un algorithme ou une API donné. De cette façon, nous pouvons apprendre des expériences des autres et empêcher la propagation de mauvaises pratiques.

Pour que cette question reste constructive, veuillez

  1. Inclure un "mauvais" exemple
  2. Expliquez ce qui ne va pas avec cet exemple
  3. Fournissez une mise en œuvre correcte (le cas échéant).
  4. Au mieux de vos capacités, fournissez des références concernant les points 2 et 3 ci-dessus.
68
goodguys_activate

Ne lancez pas votre propre crypto.

N'inventez pas votre propre algorithme ou protocole de chiffrement; c'est extrêmement sujet aux erreurs. Comme Bruce Schneier aime à le dire,

"N'importe qui peut inventer un algorithme de chiffrement qu'il ne peut pas casser lui-même; il est beaucoup plus difficile d'en inventer un que personne d'autre ne peut casser".

Les algorithmes de cryptographie sont très complexes et nécessitent une vérification intensive pour être sûr qu'ils sont sécurisés; si vous inventez le vôtre, vous n'obtiendrez pas cela, et il est très facile de se retrouver avec quelque chose d'insécurité sans s'en rendre compte.

Utilisez plutôt un algorithme et un protocole cryptographiques standard. Il y a de fortes chances que quelqu'un d'autre ait déjà rencontré votre problème et conçu un algorithme approprié à cet effet.

Votre meilleur cas est d'utiliser un schéma de haut niveau bien vérifié: pour la sécurité des communications, utilisez TLS (ou SSL); pour les données au repos, utilisez GPG (ou PGP). Si vous ne pouvez pas le faire, utilisez une bibliothèque de chiffrement de haut niveau, comme cryptlib , GPGME, Keyczar , ou NaCL , au lieu d'un un bas niveau, comme OpenSSL, CryptoAPI, JCE, etc. Merci à Nate Lawson pour cette suggestion.

76
D.W.

N'utilisez pas le cryptage sans authentification de message

C'est une erreur très courante de crypter des données sans les authentifier également.

Exemple: le développeur souhaite garder un message secret, il chiffre donc le message avec le mode AES-CBC. L'erreur: ce n'est pas suffisant pour la sécurité en présence d'attaques actives, d'attaques de rejeu, d'attaques de réaction, etc. Il existe des attaques connues de cryptage sans authentification de message, et les attaques peuvent être assez graves. Le correctif consiste à ajouter l'authentification des messages.

Cette erreur a entraîné de graves vulnérabilités dans les systèmes déployés qui utilisaient le chiffrement sans authentification, notamment ASP.NET , XML cryptage , Amazon EC2 , JavaServer Faces, Ruby on Rails, OWASP ESAPI , IPSEC , WEP , ASP.NET à nouvea , et SSH2 Vous ne voulez pas être le prochain sur cette liste.

Pour éviter ces problèmes, vous devez utiliser l'authentification des messages chaque fois que vous appliquez le chiffrement. Vous avez deux choix pour ce faire:

  • La solution la plus simple est probablement d'utiliser un schéma de cryptage qui fournit cryptage authentifié , par exemple, GCM, CWC, EAX, CCM, OCB. (Voir aussi: 1 .) Le schéma de chiffrement authentifié gère cela pour vous, vous n'avez donc pas à y penser.

  • Vous pouvez également appliquer votre propre authentification de message, comme suit. Tout d'abord, chiffrez le message à l'aide d'un schéma de chiffrement à clé symétrique approprié (par exemple, AES-CBC). Ensuite, prenez l'intégralité du texte chiffré (y compris les IV, nonces ou autres valeurs nécessaires au déchiffrement), appliquez un code d'authentification de message (par exemple, AES-CMAC, SHA1-HMAC, SHA256-HMAC) et ajoutez le résumé MAC résultant au texte chiffré avant la transmission. Du côté de la réception, vérifiez que le résumé MAC est valide avant de déchiffrer. C'est ce que l'on appelle la construction chiffrer puis authentifier. (Voir aussi: 1 , 2 .) Cela fonctionne également très bien, mais nécessite un peu plus de soin de votre part.

47
D.W.

Soyez prudent lors de la concaténation de plusieurs chaînes, avant de hacher.

Une erreur que je vois parfois: les gens veulent un hachage des chaînes S et T. Ils les concaténent pour obtenir une seule chaîne S || T, puis le hachent pour obtenir H (S || T). C'est imparfait.

Le problème: la concaténation laisse la frontière entre les deux chaînes ambiguës. Exemple: builtin || securely = built || insecurely. Autrement dit, le hachage H (S || T) n'identifie pas de manière unique la chaîne S et T. Par conséquent, l'attaquant peut être en mesure de modifier la frontière entre les deux chaînes, sans modifier le hachage. Par exemple, si Alice souhaitait envoyer les deux chaînes builtin et securely, l'attaquant pourrait les remplacer par les deux chaînes built et insecurely sans invalider le hacher.

Des problèmes similaires s'appliquent lors de l'application d'une signature numérique ou d'un code d'authentification de message à une concaténation de chaînes.

Le correctif: plutôt que la concaténation simple, utilisez un codage décodable sans ambiguïté. Par exemple, au lieu de calculer H (S || T), vous pourriez calculer H (longueur (S) || S || T), où longueur (S) est une valeur de 32 bits indiquant la longueur de S en octets. Ou, une autre possibilité est d'utiliser H (H (S) || H (T)), ou même H (H (S) || T).

Pour un exemple concret de cette faille, consultez cette faille dans Amazon Web Services ou cette faille dans Flickr [pdf].

36
D.W.

Ne réutilisez pas les nonces ou les IV

De nombreux modes de fonctionnement nécessitent un IV (vecteur d'initialisation). Vous ne devez jamais réutiliser la même valeur pour un IV deux fois; cela peut annuler toutes les garanties de sécurité et provoquer une violation catastrophique de la sécurité.

  • Pour les modes de fonctionnement de chiffrement de flux, comme le mode CTR ou le mode OFB, la réutilisation d'un IV est un désastre de sécurité. Cela peut entraîner la récupération triviale des messages chiffrés.

  • Pour d'autres modes de fonctionnement, comme le mode CBC, la réutilisation d'un IV peut également faciliter les attaques de récupération de texte en clair dans certains cas.

Quel que soit le mode de fonctionnement que vous utilisez, vous ne devez pas réutiliser le IV. Si vous vous demandez comment le faire correctement, la spécification NIST fournit une documentation détaillée sur la façon d'utiliser correctement les modes de fonctionnement du chiffrement par blocs.

Le projet Tarsnap fournit un bon exemple de cet écueil. Tarsnap crypte les données de sauvegarde en les divisant en morceaux, puis en chiffrant chaque morceau avec AES en mode CTR. Dans les versions 1.0.22 à 1.0.27 de Tarsnap, le même IV a été réutilisé par inadvertance, permettant la récupération de texte en clair.

Comment est-ce arrivé? Afin de simplifier le code Tarsnap - et dans l'espoir de réduire le potentiel de bugs - Colin Percival en a profité pour "refactoriser" le code AES-CTR dans un nouveau fichier (lib/crypto/crypto_aesctr.c dans le code source Tarsnap ) et modifié les emplacements existants où AES-CTR était utilisé pour tirer parti de ces routines. Le nouveau code ressemble à ceci:

/* Chiffrer les données. */
 - aes_ctr (& encr_aes-> clé, encr_aes-> nonce ++, buf, len, 
 - filebuf + CRYPTO_FILE_HLEN); 
 + if ((stream = 
 + crypto_aesctr_init (& encr_aes-> key, encr_aes-> nonce)) == NULL) 
 + goto err0; 
 + crypto_aesctr_stream (stream, buf, filebuf + CRYPTO_FILE_HLEN, len); 
 + crypto_aesctr_free (flux); 

Lors du refactoring, le encr_aes->nonce++ par inadvertance s'est transformé en encr_aes->nonce, et par conséquent la même valeur nonce a été utilisée à plusieurs reprises . En particulier, la valeur de nonce CTR n'est pas incrémentée après le chiffrement de chaque bloc. (Le compteur CTR est correctement incrémenté après chaque traitement de 16 octets de données, mais ce compteur est remis à zéro pour chaque nouveau bloc.) Tous les détails sont décrits par Colin Percival dans: http: //www.daemonology. net/blog/2011-01-18-tarsnap-critical-security-bug.html

29
Alex Holst

Assurez-vous de générer des générateurs de nombres aléatoires avec suffisamment d'entropie.

Assurez-vous d'utiliser des générateurs de nombres pseudo-aléatoires de crypto-force pour des choses comme la génération de clés, le choix des IV/nonces, etc. N'utilisez pas Rand(), random(), drand48() , etc.

Assurez-vous de semer le générateur de nombres pseudo-aléatoires avec suffisamment d'entropie. Ne l'ensemencez pas avec l'heure de la journée; c'est devinable.

Exemples: srand(time(NULL)) est très mauvais. Un bon moyen d'amorcer votre PRNG consiste à saisir 128 bits ou des nombres aléatoires réels, par exemple, à partir de /dev/urandom, CryptGenRandom ou similaire. En Java, utilisez SecureRandom, pas Random. Dans .NET, utilisez System.Security.Cryptography.RandomNumberGenerator, pas System.Random. En Python, utilisez random.SystemRandom, pas aléatoire. Merci à Nate Lawson pour quelques exemples.

Exemple réel: voir cette faille dans les premières versions du navigateur de Netscape , qui permettait à un attaquant de casser SSL.

29
D.W.

N'utilisez pas de chiffrement par bloc avec ECB pour le chiffrement symétrique

(S'applique à AES, 3DES, ...)

Voici un post et un très similaire article Microsoft KB concernant la façon dont le mode ECB aboutit à du code qui n'est pas chiffré.

Voir aussi ce poste similaire de Rook

Message texte en clair:

alt text

Le même message crypté avec le mode ECB (peu importe le chiffre que vous utilisez): alt text

Le même message EXACT en mode CBC (encore une fois, peu importe le chiffre que vous utilisez): alt text

Dans le mauvais sens

public static string Encrypt(string toEncrypt, string key, bool useHashing)
{

byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

if (useHashing)
    keyArray = new MD5CryptoServiceProvider().ComputeHash(keyArray);

var tdes = new TripleDESCryptoServiceProvider() 
    { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };

ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(
    toEncryptArray, 0, toEncryptArray.Length);

return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

L'erreur est dans la ligne suivante

{Key = keyArray, Mode = CipherMode.ECB , Padding = PaddingMode.PKCS7};


La bonne façon

Les bonnes personnes de Microsoft m'ont envoyé le code suivant pour corriger cet article de la base de connaissances lié ci-dessus. Ceci est référencé dans le cas # 111021973179005

Cet exemple de code utilise AES pour chiffrer les données et la clé du chiffrement AES est le code de hachage généré par SHA256. AES est l'algorithme Advanced Encryption Standard (AES). L'algorithme AES est basé sur des permutations et des substitutions. Les permutations sont des réarrangements de données et les substitutions remplacent une unité de données par une autre. AES effectue des permutations et des substitutions en utilisant plusieurs techniques différentes. Pour plus de détails sur AES, reportez-vous à l'article "Protégez vos données avec la nouvelle norme de chiffrement avancé" sur MSDN Magazine à http://msdn.Microsoft.com/en-us/magazine/cc164055.aspx .

SHA est l'algorithme de hachage sécurisé. SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) est maintenant recommandé. Pour plus d'informations sur les valeurs de hachage dans .NET Framework, reportez-vous à http://msdn.Microsoft.com/en-us/library/92f9ye3s.aspx#hash_values .

La valeur par défaut du mode de fonctionnement de l'algorithme symétrique pour AesCryptoServiceProvider est CBC. CBC est le mode de chaînage de blocs de chiffrement. Il introduit une rétroaction. Avant que chaque bloc de texte brut soit chiffré, il est combiné avec le texte chiffré du bloc précédent par une opération exclusive au niveau du bit OR. Cela garantit que même si le texte brut contient de nombreux blocs identiques, ils chaque chiffrement dans un bloc de texte chiffré différent. Le vecteur d'initialisation est combiné avec le premier bloc de texte brut par une opération exclusive au niveau du bit OR avant le chiffrement du bloc. Si un seul bit du bloc de texte chiffré est modifié, le bloc de texte brut correspondant sera également modifié. En outre, un bit du bloc suivant, dans la même position que le bit modifié d'origine, sera modifié. Pour plus d'informations sur CipherMode, veuillez voir http://msdn.Microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx .

Voici l'exemple de code.

// This function is used for encrypting the data with key and iv.
byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
    // Create an AESCryptoProvider.
    using (var aesCryptoProvider = new AesCryptoServiceProvider())
    {
        // Initialize the AESCryptoProvider with key and iv.
        aesCryptoProvider.KeySize = key.Length * 8;
        aesCryptoProvider.IV = iv;
        aesCryptoProvider.Key = key;

        // Create encryptor from the AESCryptoProvider.
        using (ICryptoTransform encryptor = aesCryptoProvider.CreateEncryptor())
        {
            // Create memory stream to store the encrypted data.
            using (MemoryStream stream = new MemoryStream())
            {
                // Create a CryptoStream to encrypt the data.
                using (CryptoStream cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
                    // Encrypt the data.
                    cryptoStream.Write(data, 0, data.Length);

                // return the encrypted data.
                return stream.ToArray();
            }
        }
    }
}

// This function is used for decrypting the data with key and iv.
byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
    // Create an AESCryptoServiceProvider.
    using (var aesCryptoProvider = new AesCryptoServiceProvider())
    {
        // Initialize the AESCryptoServiceProvier with key and iv.
        aesCryptoProvider.KeySize = key.Length * 8;
        aesCryptoProvider.IV = iv;
        aesCryptoProvider.Key = key;

        // Create decryptor from the AESCryptoServiceProvider.
        using (ICryptoTransform decryptor = aesCryptoProvider.CreateDecryptor())
        {
            // Create a memory stream including the encrypted data.
            using (MemoryStream stream = new MemoryStream(data))
            {
                // Create a CryptoStream to decrypt the encrypted data.
                using (CryptoStream cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read))
                {
                    // Create a byte buffer array.
                    byte[] readData = new byte[1024];
                    int readDataCount = 0;

                    // Create a memory stream to store the decrypted data.
                    using (MemoryStream resultStream = new MemoryStream())
                    {
                        do
                        {
                            // Decrypt the data and write the data into readData buffer array.
                           readDataCount = cryptoStream.Read(readData, 0, readData.Length);
                            // Write the decrypted data to resultStream.
                            resultStream.Write(readData, 0, readDataCount);
                        }
                        // Check whether there is any more encrypted data in stream.
                        while (readDataCount > 0);
                        // Return the decrypted data.
                        return resultStream.ToArray();
                    }
                }
            }
        }
    }
}



// This function is used for generating a valid key binary with UTF8 encoding and SHA256 hash algorithm.
byte[] GetKey(string key)
{
    // Create SHA256 hash algorithm class.
    using (SHA256Managed sha256 = new SHA256Managed())

    // Decode the string key to binary and compute the hash binary of the key.
    return sha256.ComputeHash(Encoding.UTF8.GetBytes(key));
}

Pour plus de détails sur les classes dans l'exemple de code, veuillez vous référer aux liens suivants:

· Classe AesCryptoServiceProvider

· SHA256Managed Class

· Classe CryptoStream

De plus, plusieurs articles peuvent aider à mieux comprendre la cryptographie dans .NET Framework, veuillez vous référer aux liens ci-dessous:

· Services cryptographiques

· . Modèle de cryptographie du framework .NET

· n guide simple de la cryptographie

· Chiffrement sans secrets

20
goodguys_activate

N'utilisez pas la même clé pour le cryptage et l'authentification. N'utilisez pas la même clé pour le cryptage et la signature.

Une clé ne doit pas être réutilisée à des fins multiples; qui peut ouvrir diverses attaques subtiles.

Par exemple, si vous avez une paire de clés privée/publique RSA, vous ne devez pas l'utiliser à la fois pour le chiffrement (chiffrer avec la clé publique, déchiffrer avec la clé privée) et pour signer (signer avec la clé privée, vérifier avec la clé publique ): choisissez un seul objectif et utilisez-le uniquement pour cet objectif. Si vous avez besoin des deux capacités, générez deux paires de clés, une pour la signature et une pour le chiffrement/déchiffrement.

De même, avec la cryptographie symétrique, vous devez utiliser une clé pour le chiffrement et une clé indépendante distincte pour l'authentification des messages. Ne réutilisez pas la même clé dans les deux cas.

20
D.W.

Principe de Kerckhoffs: Un cryptosystème doit être sécurisé même si tout ce qui concerne le système, à l'exception de la clé, est de notoriété publique

Un mauvais exemple: hachages LANMAN

Les hachages LANMAN seraient difficiles à comprendre si personne ne connaissait l'algorithme, mais une fois l'algorithme connu, il est maintenant très trivial de se fissurer.

L'algorithme est le suivant ( de wikipedia ):

  1. Le mot de passe de l’utilisateur ASCII est converti en majuscules.
  2. Ce mot de passe est rempli de 14 octets
  3. Le mot de passe de "longueur fixe" est divisé en deux moitiés de sept octets.
  4. Ces valeurs sont utilisées pour créer deux DES clés, une pour chaque moitié de 7 octets
  5. Chacune des deux clés est utilisée pour crypter DES la constante ASCII chaîne "KGS! @ # $%", Résultant en deux valeurs de texte chiffré de 8 octets.
  6. Ces deux valeurs de texte chiffré sont concaténées pour former une valeur de 16 octets, qui est le hachage LM

Parce que vous connaissez maintenant le texte chiffré de ces faits, vous pouvez maintenant très facilement diviser le texte chiffré en deux textes chiffrés dont vous savez qu'ils sont en majuscules, ce qui pourrait entraîner un jeu limité de caractères.

Un exemple correct: Cryptage AES

  • Algorithme connu
  • S'adapte à la technologie. Augmentez la taille des clés lorsque vous avez besoin de plus de punch cryptographique
17
Chris Dale

Essayez d'éviter d'utiliser des mots de passe comme clés de chiffrement.

Une faiblesse courante dans de nombreux systèmes est d'utiliser un mot de passe ou une phrase secrète, ou un hachage d'un mot de passe ou une phrase secrète, comme clé de chiffrement/déchiffrement. Le problème est que cela a tendance à être très sensible aux attaques de recherche de clés hors ligne. La plupart des utilisateurs choisissent des mots de passe qui n'ont pas une entropie suffisante pour résister à de telles attaques.

La meilleure solution consiste à utiliser une clé de chiffrement/déchiffrement vraiment aléatoire, et non une clé déterminée de manière déterministe à partir d'un mot de passe/phrase de passe.

Cependant, si vous devez en utiliser un basé sur un mot de passe/phrase de passe, utilisez un schéma approprié pour ralentir la recherche de clés exhaustive. Je recommande PBKDF2 , qui utilise le hachage itératif (le long des lignes de H(H(H(....H(password)...)))) pour ralentir la recherche dans le dictionnaire. Arrangez-vous pour utiliser suffisamment d'itérations pour que ce processus prenne, disons, 100 ms sur la machine de l'utilisateur pour générer la clé.

13
D.W.

Dans un protocole cryptographique: Rendez chaque message authentifié reconnaissable: deux messages ne doivent pas se ressembler

Une généralisation/variante de:

  • Soyez prudent lors de la concaténation de plusieurs chaînes, avant de hacher.
  • Ne réutilisez pas les clés.
  • Ne réutilisez pas les nonces.

Au cours d'une exécution de protocole cryptographique, de nombreux messages qui ne peuvent pas être contrefaits sans secret (clé ou non) peuvent être échangés. Ces messages peuvent être vérifiés par le destinataire parce qu'il connaît une clé publique (de signature) ou parce que seuls lui et l'expéditeur connaissent une clé symétrique ou nonce. Cela garantit que ces messages n'ont pas été modifiés.

Mais cela ne garantit pas que ces messages ont été émis au cours de la même exécution du protocole: un adversaire peut avoir capturé ces messages précédemment, ou pendant un exécution simultanée du protocole. Un adversaire peut lancer plusieurs exécutions simultanées d'un protocole cryptographique pour capturer des messages valides et les réutiliser sans modification.

En relisant intelligemment les messages, il pourrait être possible d'attaquer un protocole sans compromettre aucune clé primaire, sans attaquer aucun RNG, aucun chiffre, etc.

En rendant chaque message authentifié du protocole clairement distinct pour le récepteur, les possibilités de rejouer les messages non modifiés sont réduites (pas éliminées).

13
curiousguy

N'utilisez pas de longueurs de clé non sécurisées.

Assurez-vous d'utiliser des algorithmes avec une clé suffisamment longue.

Pour la cryptographie à clé symétrique, je recommanderais au moins une clé de 80 bits, et si possible, une clé de 128 bits est une bonne idée. N'utilisez pas de crypto 40 bits; il est peu sûr et facilement cassé par des amateurs, simplement en essayant de manière exhaustive toutes les clés possibles. N'utilisez pas de DES 56 bits; il n'est pas trivial de casser, mais il est à la portée des attaquants dédiés de casser DES. Un algorithme de 128 bits, comme AES, n'est pas beaucoup plus lent que la cryptographie 40 bits, vous n'avez donc aucune excuse pour utiliser une cryptographie minable.

Pour la cryptographie à clé publique, les recommandations de longueur de clé dépendent de l'algorithme et du niveau de sécurité requis. De plus, l'augmentation de la taille de la clé nuit aux performances, une surpuissance massive n'est donc pas économique; ainsi, cela nécessite un peu plus de réflexion que la sélection des tailles de clé à clé symétrique. Pour RSA, El Gamal ou Diffie-Hellman, je recommanderais que la clé soit d'au moins 1024 bits, au minimum absolu; cependant, les clés de 1024 bits sont à la limite de ce qui pourrait devenir fissurable à court terme et ne sont généralement pas recommandées pour une utilisation moderne, donc si possible, je recommanderais des clés de 1536 ou même de 2048 bits. Pour la cryptographie à courbe elliptique, les clés de 160 bits semblent adéquates et les clés de 224 bits sont meilleures. Vous pouvez également vous référer aux directives publiées établissant équivalences approximatives entre les tailles de clés symétriques et de clés publiques .

8
D.W.

N'utilisez pas la même clé dans les deux sens.

Dans les communications réseau, une erreur courante consiste à utiliser la même clé pour la communication dans le sens A-> B que pour le sens B-> A. C'est une mauvaise idée, car elle permet souvent de rejouer des attaques qui rejouent quelque chose A envoyé à B, de retour à A.

L'approche la plus sûre consiste à négocier deux clés indépendantes, une pour chaque direction. Alternativement, vous pouvez négocier une seule clé K, puis utiliser K1 = AES (K, 00..0) pour une direction et K2 = AES (K, 11..1) pour l'autre direction.

8
D.W.

Un pad à usage unique n'est pas un pad à usage unique si la clé est étirée par un algorithme

L'identifiant "bloc unique" (également connu sous le nom de chiffrement Vernam) est fréquemment mal appliqué à diverses solutions cryptographiques dans le but de revendiquer une sécurité incassable. Mais par définition, un chiffrement Vernam est sécurisé si et seulement si ces trois conditions sont remplies:

  • Le matériau clé est vraiment imprévisible; ET
  • Le matériau clé est de la même longueur que le texte en clair; ET
  • Le matériau clé n'est jamais réutilisé.

Toute violation de ces conditions signifie qu'il ne s'agit plus d'un chiffrement ponctuel.

L'erreur courante est qu'une touche courte est étirée avec un algorithme. Cette action viole la règle d'imprévisibilité (sans parler de la règle de longueur de clé.) Une fois cela fait, le pavé unique est mathématiquement transformé en l'algorithme d'étirement des clés. La combinaison de la clé courte avec des octets aléatoires ne modifie que l'espace de recherche nécessaire pour forcer brutalement l'algorithme d'étirement des clés. De même, l'utilisation d'octets "générés de manière aléatoire" transforme l'algorithme du générateur de nombres aléatoires en algorithme de sécurité.

Voici un exemple simple. J'ai un message que je vais crypter en utilisant un "tampon à usage unique" qui utilise une fonction cryptographiquement sécurisée comme générateur de clés. J'ai choisi une clé secrète, puis y ai ajouté un nombre aléatoire pour m'assurer qu'elle ne sera pas réutilisée. Comme je ne réutilise pas la clé, il n'y a aucun moyen d'attaquer le texte chiffré en soustrayant un message d'un autre.

          plaintext : 1234567890123456789012345678901234567890
       key material : 757578fbf23ffa4d748e0800dd7c424a46feb0cc
OTP function (xor)  : ----------
         ciphertext : 67412E83622DCE1B0C1E1A348B04D25872A8C85C

Le matériel clé a été généré en toute sécurité à l'aide de SHA-1 pour hacher mon mot de passe secret (plus aléatoire) afin de l'étirer. Mais tout attaquant qui connaît l'algorithme d'étirement * utilisé est SHA-1 peut l'attaquer en essayant diverses entrées dans SHA-1 et en XORant la sortie avec le texte chiffré. Deviner la clé "OTP" n'est plus plus difficile que de deviner les entrées combinées de l'algorithme cryptographique. Cette propriété est vraie quel que soit l'algorithme cryptographique de base choisi, les mesures de complexité qu'il détient ou la façon dont il est implémenté ou prédéfini.

Vous pouvez avoir un très bon algorithme d'étirement des clés. Vous pouvez également avoir un générateur de nombres aléatoires très sécurisé. Cependant, votre algorithme n'est par définition pas un tampon à usage unique et n'a donc pas la propriété incassable d'un tampon à usage unique.

* L'application du principe de Kerckhoff signifie que vous devez supposer que l'attaquant peut toujours déterminer les algorithmes utilisés.

3
John Deters

Utilisez le bon mode

De même, ne comptez pas sur les paramètres par défaut de la bibliothèque pour être sécurisé. Plus précisément, de nombreuses bibliothèques qui implémentent AES implémentent l'algorithme décrit dans FIPS 197, qui est ce qu'on appelle le mode ECB (Electronic Code Book), qui est essentiellement un mappage simple de:

AES(plaintext [32]byte, key [32]byte) -> ciphertext [32]byte

est très précaire. Le raisonnement est simple, alors que le nombre de clés possibles dans l'espace de clés est assez important, le maillon faible ici est la quantité d'entropie dans le message. Comme toujours, xkcd.com décrit est meilleur que moi http://xkcd.com/257/

Il est très important d'utiliser quelque chose comme CBC (Cipher Block Chaining) qui fait essentiellement du chiffrement [i] un mappage:

ciphertext[i] = SomeFunction(ciphertext[i-1], message[i], key)

Juste pour signaler quelques bibliothèques de langues où ce genre d'erreur est facile à faire: http://golang.org/pkg/crypto/aes/ fournit une implémentation AES qui, si elle était utilisée naïvement, résultat en mode ECB.

La bibliothèque pycrypto utilise par défaut le mode ECB lors de la création d'un nouvel objet AES.

OpenSSL, fait bien cela. Chaque appel AES est explicite sur le mode de fonctionnement. Vraiment, la chose la plus sûre que l'OMI est d'essayer de ne pas faire vous-même un cryptage de bas niveau. Si vous y êtes forcé, procédez comme si vous marchiez sur du verre brisé (avec précaution), et essayez de vous assurer que vos utilisateurs ont raison de vous faire confiance pour protéger leurs données.

3
Shane Hansen

Ne réutilisez pas la même clé sur de nombreux appareils.

Plus vous partagez une clé cryptographique plus largement, moins vous aurez de chances de la garder secrète. Certains systèmes déployés ont réutilisé la même clé symétrique sur chaque périphérique du système. Le problème, c'est que tôt ou tard, quelqu'un extraira la clé d'un seul appareil, puis il pourra attaquer tous les autres appareils. Alors ne fais pas ça.

Voir aussi "Cryptage symétrique Ne pas # 6: ne pas partager une seule clé sur plusieurs appareils" dans cet article de blog . Crédits à Matthew Green.

3
D.W.

N'utilisez pas d'OTP ou de chiffrement de flux pour le chiffrement de disque

exemple 1

Supposons que deux fichiers soient enregistrés à l'aide d'un chiffrement de flux/OTP. Si le fichier est réenregistré après une modification mineure, un attaquant peut voir que seuls certains bits ont été modifiés et déduire des informations sur le document. (Imaginez changer la salutation "Cher Bob" en "Chère Alice").

exemple 2

Il n'y a aucune intégrité dans la sortie: un attaquant peut modifier le texte chiffré et modifier le contenu des données en XOR simplement les données.

À emporter: les modifications apportées au texte chiffré ne sont pas détectées et ont un impact prévisible sur le texte en clair.

Solution

Utilisez un chiffrement par bloc pour ces situations qui inclut des vérifications d'intégrité des messages

1

Ne faites pas confiance aux normes.

De nombreuses normes existent en cryptographie, et parfois vous devez les utiliser. Mais ne présumez pas que les personnes qui rédigent les normes ont bien compris la cryptographie dont elles avaient besoin. Par exemple, EAX a été retravaillé dans une norme de mise en réseau. EAX a une preuve de sécurité. La version retravaillée ne l'a pas fait.

MD5 est une norme. Il est maintenant cassé. Puce et PIN a été cassé à plusieurs reprises, grâce à une abondance de fonctionnalités dangereuses. GPG prend toujours en charge les clés DSA qui sont trop courtes pour le confort. SSL a des options qui ne devraient pas être utilisées, et nécessite attention à les éviter.

Que peut-on faire à ce sujet? Être prudent, comprendre les risques connus et suivre la recherche de nouveaux risques.

1
Watson Ladd

tilisez uniquement des MAC qui ne sont pas vulnérables aux attaques par extension de message

Un MAC est un code de hachage qui garantit l'intégrité du message (pas de modifications, etc.) d'un texte brut donné. De nombreuses implémentations et normes publiées ne parviennent pas à protéger un MAC contre un attaquant qui ajoute des données supplémentaires au MAC.

La solution est que l'implémentation MAC utilise une deuxième clé (différente) et rechiffre la sortie finale.

ECBC et NMAC sont des exemples de chiffres qui empêchent correctement l'attaque d'extension de message.

Solution:

  • Utilisez Encrypted CBC (ECBC) au lieu de raw CBC
  • Utilisez NMAC au lieu de cascade
0

N'utilisez jamais une clé à usage unique (OTP) ou une clé de chiffrement de flux plus d'une fois

Un OTP appliqué deux fois signifie que les données cryptées avec un "secret parfait" seront décryptées et en clair. Cela se produit car les données sont XOR deux fois.

Exemple

Supposons qu'un OTP/ou un flux avec la même clé est réutilisé.

Un attaquant collecte un grand nombre de données envoyées d'un client à un serveur et XOR ensemble un ensemble de deux paquets jusqu'à ce que les deux paquets se décryptent (ou sous-ensemble).

Le codage ASCII a suffisamment de redondance, ce qui signifie qu'avec suffisamment de texte chiffré, les messages originaux pourraient être décodés (avec la clé OTP secrète).

Exemples du monde réel

  • Projet Vérone (1941-46) pour un exemple d'un OTP utilisé par les Russes et a ensuite été décrypté par l'agence de renseignement américaine

  • PPTPv1 de Microsoft, le client et le serveur chiffrent les données à l'aide de la même clé.

  • WEP réutilise la même clé une fois que 2 ^ 24 paquets sont envoyés, ou si une carte NIC est réinitialisée. Le premier problème est dû au fait que l'IV est de 24 bits, ce qui fait qu'après 16 millions de trames sont transmis un tampon de temps est créé. Le deuxième problème se produit dans les implémentations matérielles où, après un cycle d'alimentation, l'IV se remet à zéro, ce qui entraîne un tampon de deux temps. Ce problème est facile à voir car le IV est envoyé en clair.

Recommandations

  • Une nouvelle clé doit être créée pour chaque session (par exemple TLS).

  • Le client doit utiliser un OTP (ou un chiffrement de flux avec PRG) avec le serveur, et le serveur doit utiliser un clé différente lors du chiffrement des données vers le client

  • Plutôt que de générer de nombreuses clés, il est possible de développer une seule clé en un long flux à l'aide d'un PRG (en supposant que vous faites confiance au PRG) et d'utiliser chaque segment de cette extension comme clé.

  • Sachez que tous les PRG ne sont pas conçus pour fonctionner en mode incrémentiel et qu'une entrée aléatoire peut être requise. (RC4 a ce problème en mode incrémentiel)

0

N'utilisez pas RC4

RC4 a été conçu en 1987 pour être utilisé comme chiffrement de flux. Il est utilisé en HTTPS et WEP.

Il y a des faiblesses

  1. Il y a un biais dans la sortie initiale: Pr [2ème octet = 0] = 2/256
  2. La probabilité que seize bits soient égaux à zéro est de 1/256 ^ 2 + 1/256 ^ 3. Cela se produit après que plusieurs Go de données ont été chiffrés.
  3. Vulnérable aux attaques de clés associées, où seul l'IV change mais la clé reste la même.

À retirer Si vous devez utiliser RC4, ignorez les 256 premiers octets car ils sont biaisés. Si vous utilisez RC4 pour des gigantesques de données, alors le biais dans RC4 permettra des attaques de toutes les données cryptées antérieures.

0

Utilisez des processeurs de flux modernes qui fonctionnent correctement dans le matériel ou le logiciel

Tous les chiffrements de flux ne sont pas conçus pour être implémentés dans du matériel ou des logiciels. registre à décalage à rétroaction linéaire (LFSR) est un exemple de chiffrement matériel largement déployé qui est facilement cassé.

LFSR est utilisé dans:

  • Cryptage DVD (également appelé CSS) 2 LFSR
  • Cryptage GSM (A5/1.2) 3 LSFR
  • Bluetooth (E0): 4 LFSR

Le matériel pour ce qui précède est largement déployé et donc difficile à mettre à jour ou à mettre aux normes modernes. Tous les éléments ci-dessus sont gravement endommagés et ne doivent pas faire confiance pour des communications sécurisées.

Attaque:

Étant donné que la clé est divisée en deux sections pendant le cryptage (17 bits et 25 bits) et que ces bits sont utilisés pour crypter le même texte de chiffrement, il est possible d'utiliser la connaissance du format MPEG et de forcer une clé 17 bits pour extrapoler ce que la clé 25 bits est.

Ce n'est pas nouveau, mais FOSS est facile à trouver et illustre ce problème.

Solution:

Le projet eStream (en 2008) a qualifié 5 chiffrements de flux à utiliser. Une différence notable est qu'au lieu d'utiliser une clé avec un IV, les chiffres utilisent une clé, un nonce et un compteur. Salsa20 fonctionne de cette façon et est conçu pour être utilisé facilement à la fois au niveau matériel et logiciel. Plus précisément, il est inclus dans le jeu d'instructions x86 SSE2.

À part

Les chiffres modernes sont non seulement plus sûrs, mais ils sont également plus rapides:

PRG          Speed (MB/sec)
RC4              126         (obsolete)
Salsa20/12       643         (modern)
Sosemaunk        727         (modern)
0