Question:
Leçons apprises et idées fausses concernant le chiffrement et la cryptologie
goodguys_activate
2011-02-20 01:25:34 UTC
view on stackexchange narkive permalink

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

Le but de cette question est d'identifier et de lister ce que ne 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 garder cette question constructive, veuillez

  1. Inclure un "faux" exemple
  2. Expliquez ce qui ne va pas avec cet exemple
  3. Fournissez une implémentation correcte (le cas échéant).
  4. Au mieux de vos capacités, fournissez des références concernant les n ° 2 et 3 ci-dessus.
Les erreurs les plus courantes ne sont pas des erreurs dans le code, mais plutôt des idées fausses sur la façon d'utiliser la cryptographie. En d'autres termes, le développeur ferait probablement la même erreur dans n'importe quelle langue. Par conséquent, je recommande d'élargir la question afin qu'elle ne se concentre pas trop sur le code; la plupart des erreurs sont des erreurs conceptuelles et non des défauts de codage.
Même si une réponse est acceptée, continuez à ajouter les leçons apprises. À tout le moins, ce sera éducatif.
Aussi, présentation courte et facile de Colin Percival (tarsnap): http://www.bsdcan.org/2010/schedule/attachments/135_crypto1hr.pdf
Ne faites pas de cryptographie si vous avez besoin de lire des listes «à ne pas faire». Demandez à un ingénieur en sécurité spécialisé en cryptographie de vous aider. :)
Méta discussion connexe: [Clarification entre «rouler votre propre cryptographie» et «mettre en œuvre une norme»] (http://meta.security.stackexchange.com/q/1119/396)
Dans la plupart des cas, ne faites pas de cryptographie si vous pensez que vous n'avez pas besoin de préparer la liste "à ne pas faire" (https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect) - Dave était sûr sa mise en œuvre était sûre.
Même si cette question couvre des problèmes très importants, son format ne convient pas très bien aux sites SE, car il interroge essentiellement une «liste de X» qui ne fonctionne pas bien.
21 réponses:
#1
+76
D.W.
2011-02-20 09:52:34 UTC
view on stackexchange narkive permalink

Ne lancez pas votre propre crypto.

N'inventez pas votre propre algorithme ou protocole de cryptage; 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 briser 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 un contrôle intensif 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 vous en rendre compte.

À la place, utilisez 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 ait conçu un algorithme approprié à cette fin.

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 faire cela, utilisez une bibliothèque cryptographique de haut niveau, telle que cryptlib, GPGME, Keyczar ou NaCL, au lieu d'un de bas niveau, comme OpenSSL, CryptoAPI, JCE, etc. Merci à Nate Lawson pour cette suggestion.

En fait, cela devrait être la règle numéro 1 - qui invaliderait toutes nos autres règles. Il n'y a probablement que quelques centaines de personnes dans le monde qui devraient concevoir ou mettre en œuvre la cryptographie. Le reste d'entre nous devrait simplement utiliser leur API (saine).
Quelle est la meilleure option pour un développeur .NET? Des tutoriels ou des exemples? Il est difficile pour un non-crypto-expert de déterminer les fausses informations à partir de ce qui est valide.
Il est particulièrement tentant pour l'ingénieur créatif qui a résolu des problèmes difficiles dans le passé de laisser la crypto à quelqu'un d'autre. Il y a encore beaucoup de problèmes difficiles et difficiles à résoudre en dehors de la crypto. Regardez les exemples de personnes qui ont commis des erreurs critiques dans la cryptographie et résolvez autre chose.
+1 L'API Crypto offre trop de flexibilité qui peut causer des ennuis au développeur profane. Il existe de nombreux exemples sur Internet (et sur le site d'assistance de MSFT) qui enfreignent au moins l'une des leçons apprises sur cette page. Certains développeurs oublient de prendre en compte des éléments tels que la manière dont les clés sont échangées, validées et révoquées. C'est là que les choses deviennent épineuses. Où sont les clés? Comment les clés sont-elles publiées? Comment les clés sont-elles validées? Comment s'effectue la rotation des clés? Même si le développeur a la chance de faire le bon calcul ou une combinaison de fonctionnalités (CBC, Block, stream, etc.), le protocole peut être rompu.
Pour une option de haut niveau pour .net, j'ai porté [keyczar vers C #] (http://jbtule.github.com/keyczar-dotnet/).
"utiliser TLS" sans impressions fines n'est pas une si bonne idée, quand on voit [this] (http://www.isg.rhul.ac.uk/tls/)
Ce ne peut pas être une règle de cryptologie de ne pas inventer la cryptographie, et ce n'est pas une mauvaise utilisation d'une API ou d'un algorithme existant.
#2
+47
D.W.
2011-02-20 09:36:29 UTC
view on stackexchange narkive permalink

N'utilisez pas le chiffrement sans authentification des messages

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

Exemple: le développeur veut garder un message secret, donc crypte 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 relecture, d'attaques de réaction, etc. Il existe des attaques connues sur le chiffrement sans authentification de message, et les attaques peuvent être assez graves. Le correctif consiste à ajouter une 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 chiffrement, Amazon EC2, JavaServer Faces, Ruby on Rails, OWASP ESAPI, IPSEC, WEP, ASP.NET à nouveau et SSH2. Vous ne voulez pas être le prochain sur cette liste.

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

  • La solution la plus simple consiste probablement à utiliser un schéma de chiffrement qui fournit un chiffrement 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.

  • Sinon, vous pouvez appliquer votre propre authentification de message, comme suit. Tout d'abord, cryptez le message à l'aide d'un schéma de cryptage à 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 pour le déchiffrement), appliquez un code d'authentification de message (par exemple, AES-CMAC, SHA1-HMAC, SHA256-HMAC), et ajoutez le condensé MAC résultant au texte chiffré avant la transmission. Du côté de la réception, vérifiez que le condensé MAC est valide avant de déchiffrer. C'est ce qu'on appelle la construction chiffrer puis authentifier. (Voir aussi: 1, 2.) Cela fonctionne également bien, mais nécessite un peu plus d'attention de votre part.

Les utilisateurs de C # et Java devraient consulter [BouncyCastle] (http://www.bouncycastle.org/csharp/)
Le chiffrement GCM @makerofthings7: est inclus dans le fournisseur Oracle dans Java 7. Il est également proposé pour le chiffrement TLS (dans un RFC) et XML v1.1. L'implémentation Bouncy est compatible avec celle du fournisseur Sun (à l'exception des différences concernant les données authentifiées et l'exception exacte levée).
Pour ceux qui sont nouveaux dans la cryptographie (d'où la lecture de cet article), "l'authentification" n'a rien à voir avec la "connexion" ou l'utilisation de vos informations d'identification. C'est quelque chose comme une somme de contrôle. En réalité, c'est la combinaison des mathématiques et des processus qui fait en fin de compte beaucoup plus que la simple somme de contrôle des données. (@D.W. Que pensez-vous de cette explication profane?)
@makerofthings7, excellente explication! Il serait peut-être plus clair si l'article faisait référence à «l'authentification des messages» plutôt qu'à l'authentification générique. Je vais faire ce changement maintenant.
#3
+36
D.W.
2011-02-20 11:29:57 UTC
view on stackexchange narkive permalink

Faites attention lors de la concaténation de plusieurs chaînes, avant le hachage.

Une erreur que je vois parfois: les gens veulent un hachage des chaînes S et T.Ils les concaténent pour obtenir un chaîne unique S || T, puis hachez-la pour obtenir H (S || T). Ceci est imparfait.

Le problème: la concaténation laisse la frontière entre les deux chaînes ambiguë. Exemple: intégré || sécurisé = construit || non sécurisé . En d'autres termes, 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 changer la frontière entre les deux chaînes, sans changer le hachage. Par exemple, si Alice voulait envoyer les deux chaînes builtin et en toute sécurité , l'attaquant pourrait les changer en deux chaînes built et de manière non sécurisée sans invalider le hachage.

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 qu'une simple concaténation, utilisez un encodage décodable sans ambiguïté. Par exemple, au lieu de calculer H (S || T), vous pouvez 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 réel de cette faille , consultez cette faille dans Amazon Web Services ou cette faille dans Flickr [pdf].

Je lance généralement HMAC dessus. Un peu plus cher, mais au moins je n'ai pas besoin de le mettre en œuvre moi-même.
@CodeInChaos,, ces problèmes s'appliquent également à HMAC. HMAC ne fait rien pour vous aider si vous concaténez plusieurs chaînes avant de les transmettre à HMAC.
Ce que je voulais dire, c'est que j'utilise l'un comme clé, l'autre comme message.
Bien @CodeInChaos,, utilisez ce qui fonctionne pour vous, si vous avez suffisamment confiance en vos compétences cryptographiques pour éviter les failles. Personnellement, je ne recommanderais pas cette approche aux autres. (1) Ce n'est pas pour cela que HMAC a été conçu, donc s'il est sécurisé, vous "avez de la chance". (2) Cela se limite au cas de deux champs. Si vous avez trois champs, vous devez faire quelque chose de plus complexe. Ainsi pourrait tout aussi bien utiliser une défense appropriée dès le début, comme l'utilisation d'un codage décodable sans ambiguïté (par exemple, longueur avant chaque champ à concaténer).
Que diriez-vous de H (H (S) || H (T))? puisque la sortie de H () est une longueur fixe, vous ne pourriez pas déplacer la frontière. De plus, l'utilisation de hachages comme entrées pour la concaténation rend très difficile la manipulation d'une chaîne d'un côté de l'une des entrées dans une valeur souhaitée. Le seul inconvénient que je vois est que vous faites maintenant 3 hachages au lieu d'un. Mais encore une fois, les hachages sont censés être lents, alors peut-être que ce n'est pas une mauvaise chose après tout;)
@Marcin, oui, c'est une autre façon raisonnable de le faire. J'ai ajouté votre suggestion à ma réponse. Merci pour la suggestion! (Il peut y avoir des cas très obscurs où ce n'est pas une bonne solution - par exemple, où S est un secret, H (S) est de notoriété publique, T est un défi, et le but était que l'expéditeur prouve la connaissance de S en renvoyant un hachage de S et T - mais je ne vais pas m'inquiéter de ces très rares cas spéciaux.)
@Marcin "_hashes censées être lentes_" non, elles ne sont ** pas ** censées être lentes, et elles ne sont ** pas ** lentes non plus
L'exigence ici est de connaître la limite sans ambiguïté: l'approche de hachage-concaténation-hachage nécessite que vous hachiez au moins tous les éléments sauf un - un élément dans une position connue peut être laissé sans hachage. Ainsi, vous pouvez éviter d'utiliser H (S) s'il s'agit d'une quantité connue utilisée pour l'authentification - à la place en utilisant S mais en hachant tous les autres composants. Soyez prudent, de toute façon, car les mathématiques sous-jacentes peuvent vous mordre sous des variantes de concaténation et de re-hachage.
Je suis un crypto-n00b, donc cela peut être une question stupide, mais si vous essayez d'obtenir le hachage de deux chaînes `builtin` et` securely`, pourquoi ne pas utiliser le hash H (`builtin` || [somedelimiter ] || `en toute sécurité`)?
@Matt, yup, ça peut marcher! Cependant, vous devrez échapper à toutes les instances du délimiteur dans ces chaînes (sinon, inévitablement, quelqu'un tapera une chaîne contenant le délimiteur, puis cette approche s'effondrera). Cela ajoute de la complexité non présente dans les alternatives. Et si vous le recommandez à d'autres, inévitablement l'un de vos spectateurs oubliera d'échapper aux délimiteurs. S'ils oublient d'échapper au délimiteur, ce schéma échoue tranquillement: il n'est pas sécurisé, mais ils ne le remarqueront probablement pas en fonctionnement normal. Donc, oui, cela fonctionne - mais ce n'est peut-être pas mon premier choix.
`H (json_encode (array (" builtin "," securely ")))` pourrait le faire. Et @penguat. Realex Payments utilise un hash de cette forme dans le traitement des cartes de crédit: `H (H (divers) | secret)`.
Quoi ??? Cette réponse n'a aucun sens. Si les données sont ambiguës, il n'est pas nécessaire qu'il y ait un attaquant. Alice ne sait pas comment interpréter "builtinsecurely" parce que Bob n'a pas mis d'espace. Cette ambiguïté n'est pas un problème introduit par l'attaquant, mais est plutôt inhérente à la représentation des données choisie. Comment pouvons-nous digérer quoi que ce soit si nous ne pouvons pas caténer? Chaque message de plus d'un bit est une caténation.
@Kaz, votre confusion serait tout à fait valable si nous parlions du formatage de l'entrée au cryptage (où le récepteur va déchiffrer puis essayer de donner un sens au texte en clair). Mais ce n'est pas la situation ici. Ici, nous parlons de formater l'entrée dans une fonction de hachage. Ici, il n'y a pas d'analogue du déchiffrement; le récepteur ne prend jamais le texte en clair et essaie ensuite de l'analyser. Au lieu de cela, le destinataire recrée le même texte en clair, le hache et voit s'il correspond au hachage envoyé par l'expéditeur. Par conséquent, le protocole semble fonctionner correctement en l'absence d'un attaquant.
@D.W. Ai-je dit crypter? Je voulais écrire "digérer". Là, je l'ai réparé. Bonne chose s.e. nous permet de modifier les commentaires des heures après leur rédaction.
D'accord, nous avons donc deux chaînes "builtin" et "secure". Nous les avons assemblées de manière à ce qu'il n'y ait pas de frontière «construite de manière sûre». L'endroit où se situe la division n'est pas du tout représenté dans le message de quelque manière que ce soit. Pas de bits ou d'octets de cadrage, pas de champs de longueur, rien. Et puis nous le hachons. Et donc maintenant l'attaquant "change la frontière". Comment l'attaquant * change-t-il * ce qui * n'est pas là *?
Et si je mets deux bits ensemble et que je les hache, ne suis-je pas en train de caténer des chaînes? Il faut donc hacher chaque bit séparément pour qu'il soit identifié. Nous ne voudrions pas que les attaquants déplacent les frontières entre les bits afin que 00 1 devienne soudainement 0 11.
@Kaz, voici un cas que j'ai vu à plusieurs reprises: l'expéditeur envoie un message en deux parties, «intégré» et «sécurisé». Le message est en texte clair et dans le message, la division est rendue explicite. Pour protéger son intégrité, l'expéditeur ajoute un MAC ou un hachage ou une signature sur la concaténation des parties du message. Le défaut: un homme du milieu peut changer le message intégré / sécurisé en construit / non sécurisé; les deux ont le même hachage / signature / MAC, de sorte que le destinataire ne peut pas le détecter. Lisez les deux exemples auxquels je renvoie (AWS et Flickr) pour comprendre comment cela peut se produire plus en détail. Oui, c'est * un vrai défaut.
@DW Eh bien oui, puisque la division est explicite dans le message, mais ces bits ne sont pas inclus dans le hachage !!! Ne hachez pas la charge utile et omettez l'en-tête ou les métadonnées. Hash tout le message. Ce n'est pas un problème de caténation. Tout ce que vous excluez d'un hachage n'est pas protégé par celui-ci, quel qu'il soit. Champ de longueur qui divise la charge utile en deux parties, horodatage ou autre.
#4
+29
Alex Holst
2011-02-20 02:11:32 UTC
view on stackexchange narkive permalink

Ne réutilisez pas les nonces ou les IVs

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

  • Pour les modes de fonctionnement de chiffrement de flux, comme le mode CTR ou le mode OFB, réutiliser un IV est un désastre de sécurité. Cela peut rendre les messages chiffrés facilement récupérables.

  • 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 brut dans certains cas .

Quel que soit le mode de fonctionnement que vous utilisez, vous ne devez pas réutiliser l'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 cela s'est-il passé? Afin de simplifier le code de 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 de Tarsnap ) et modifié les emplacements existants où AES-CTR a été utilisé pour profiter de ces routines. Le nouveau code ressemble à ceci:

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

Lors de la refactorisation, encr_aes->nonce ++ a été transformé par inadvertance en encr_aes->nonce , et par conséquent la même valeur nonce a été utilisée à plusieurs reprises . En particulier, la valeur nonce CTR n'est pas incrémentée après que chaque bloc est chiffré. (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

Puisque le problème est centré sur un nonce, essayez de titrer cette réponse dans ce sens (+1); Q: un nonce est-il généralement ++, ou doit-il être aléatoire?
@makerofthings, cela dépend de l'algorithme. Certains algorithmes et modes de fonctionnement nécessitent des nonces aléatoires (par exemple, le mode CBC); d'autres exigent seulement que les nonces soient distincts, et donc un compteur suffit (par exemple, le mode CTR). Espérons que la spécification de l'algorithme / mode de fonctionnement décrira ce qui est requis.
Je suggère que la réponse soit modifiée pour inclure également les IV. L'utilisation correcte de IV / nonce sont des idées très similaires.
Nonce est N une fois. Oui, n'utilisez la variable N qu'une seule fois. Singulier. Ne répétez pas. La force de l'algorithme associé est affectée par la répétition de N.
Voici un mauvais exemple: WEP a implémenté RC4 avec un nonce 24 bits qui augmente après chaque message. Cela a introduit deux problèmes: (1) après l'envoi de 2 ^ 24 paquets, les nonces ont été réutilisés. (2) RC4 n'a pas été conçu pour avoir des nonces "étroitement liés" où l'on sait que chaque chiffre suivant était ++ la valeur du précédent.
Voici un bon exemple: supposons qu'un concepteur de crypto ne souhaite pas réutiliser la même clé pour plusieurs messages. Une solution consiste à générer une clé et à l'étendre à l'aide d'un PRG. Ensuite, n'utilisez que chaque multiple de «x» bits comme clé. Où segment 1 = = touche 1, segment 2 = = touche 2.
#5
+29
D.W.
2011-02-20 10:06:23 UTC
view on stackexchange narkive permalink

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

Assurez-vous d'utiliser des générateurs de nombres pseudo-aléatoires à 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 ensemencer le générateur de nombres pseudo-aléatoires avec suffisamment d'entropie. Ne le semez 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 est de récupérer 128 bits ou des nombres véritablement aléatoires, par exemple à partir de / dev / urandom , CryptGenRandom ou similaire. En Java, utilisez SecureRandom et non Random. Dans .NET, utilisez System.Security.Cryptography.RandomNumberGenerator et non System.Random. En Python, utilisez random.SystemRandom, pas aléatoire. Merci à Nate Lawson pour quelques exemples.

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

Je me souviens avoir appris Basic sur mon Apple] [e. J'écrivais un jeu et j'avais besoin d'une entrée aléatoire, j'ai donc utilisé RND (1). J'ai dû continuer à redémarrer pour déboguer mon jeu et j'ai remarqué que l'élément aléatoire allait toujours dans le même ordre après le démarrage. C'est alors que j'ai découvert les générateurs de nombres pseudo-aléatoires. Si vous avez besoin de graines aléatoires, Random.org propose une génération de nombres aléatoires gratuite basée sur le bruit atmosphérique.
Random.org est le meilleur pour la simulation et d'autres fins non liées à la sécurité. Random.org n'est pas une bonne base pour une graine pour un PRNG cryptographique, car vous ne pouvez pas croire qu'il est inconnu des autres.
#6
+20
goodguys_activate
2011-02-20 01:34:06 UTC
view on stackexchange narkive permalink

Voici un article et un article de la base de connaissances Microsoft très similaire sur la manière dont le mode ECB génère du code qui n'est pas chiffré.

Voir également ce message similaire de Rook

Message en texte clair:

alt text

Le même message chiffré en mode ECB (peu importe le chiffrement que vous utilisez): alt text

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

La mauvaise manière

  chaîne statique publique Encrypt (chaîne toEncrypt, clé de chaîne, bool useHashing) { byte [] keyArray = UTF8Encoding.UTF8.GetBytes (key); byte [] toEncryptArray = UTF8Encoding.UTF8.GetBytes (toEncrypt); if (useHashing) keyArray = new MD5CryptoServiceProvider (). ) {Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7}; ICryptoTransform cTransform = tdes.CreateEncryptor (); byte [] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEntrcryptArray.Tength) (resultArray, 0, resultArray.Length);}  

L'erreur est dans la ligne suivante

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


La bonne manière

Les bonnes gens 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 crypter les données, et la clé du cryptage 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 d'informations sur AES, reportez-vous à l'article «Protégez vos données avec la nouvelle norme de chiffrement avancée» sur MSDN Magazine à l'adresse 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 des commentaires. Avant que chaque bloc de texte brut ne soit chiffré, il est combiné avec le texte chiffré du bloc précédent par une opération OU exclusive au niveau du bit. Cela garantit que même si le texte brut contient de nombreux blocs identiques, chacun sera chiffré 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 OU exclusive au niveau du bit avant que le bloc ne soit chiffré. Si un seul bit du bloc de texte chiffré est mutilé, le bloc de texte brut correspondant sera également mutilé. De plus, un morceau du bloc suivant, dans la même position que le bit mutilé d'origine, sera mutilé. Pour plus d'informations sur CipherMode , veuillez consulter http://msdn.microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx.

Voici l'exemple de code.

  // Cette fonction est utilisée pour crypter les données avec la clé et iv.
byte [] Encrypt (byte [] data, byte [] key, byte [] iv) {// Créer un AESCryptoProvider. using (var aesCryptoProvider = new AesCryptoServiceProvider ()) {// Initialisez l'AESCryptoProvider avec la clé et iv. aesCryptoProvider.KeySize = key.Length * 8; aesCryptoProvider.IV = iv; aesCryptoProvider.Key = clé; // Créer un chiffreur à partir de AESCryptoProvider. using (ICryptoTransform encryptor = aesCryptoProvider.CreateEncryptor ()) {// Créer un flux mémoire pour stocker les données chiffrées. using (MemoryStream stream = new MemoryStream ()) {// Créez un CryptoStream pour crypter les données. using (CryptoStream cryptoStream = new CryptoStream (stream, encryptor, CryptoStreamMode.Write)) // Crypter les données. cryptoStream.Write (données, 0, données.Longueur); // renvoie les données chiffrées. retourne stream.ToArray (); }}}} // Cette fonction est utilisée pour déchiffrer les données avec la clé et iv.byte [] Decrypt (byte [] data, byte [] key, byte [] iv) {// Créer un AESCryptoServiceProvider. using (var aesCryptoProvider = new AesCryptoServiceProvider ()) {// Initialisez AESCryptoServiceProvier avec la clé et iv. aesCryptoProvider.KeySize = key.Length * 8; aesCryptoProvider.IV = iv; aesCryptoProvider.Key = clé; // Créer un déchiffreur à partir de AESCryptoServiceProvider. using (ICryptoTransform decryptor = aesCryptoProvider.CreateDecryptor ()) {// Créer un flux mémoire comprenant les données chiffrées. using (MemoryStream stream = new MemoryStream (data)) {// Créez un CryptoStream pour décrypter les données chiffrées. using (CryptoStream cryptoStream = new CryptoStream (stream, decryptor, CryptoStreamMode.Read)) {// Créer un tableau de tampons d'octets.
byte [] readData = nouvel octet [1024]; int readDataCount = 0; // Crée un flux mémoire pour stocker les données déchiffrées. using (MemoryStream resultStream = new MemoryStream ()) {do {// Décrypter les données et écrire les données dans le tableau de tampons readData. readDataCount = cryptoStream.Read (readData, 0, readData.Length); // Ecrit les données déchiffrées dans resultStream. resultStream.Write (readData, 0, readDataCount); } // Vérifiez s'il n'y a plus de données chiffrées dans le flux. while (readDataCount > 0); // Renvoie les données déchiffrées. return resultStream.ToArray (); }}}}}} // Cette fonction est utilisée pour générer un binaire de clé valide avec un codage UTF8 et un algorithme de hachage SHA256.byte [] GetKey (clé de chaîne) {// Créer une classe d'algorithme de hachage SHA256. using (SHA256Managed sha256 = new SHA256Managed ()) // Décode la clé de chaîne en binaire et calcule le binaire de hachage de la clé. 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

· Classe SHA256Managed

· Classe CryptoStream

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

· Services de cryptographie

· Modèle de cryptographie .NET Framework

· Un guide simple de la cryptographie

· Chiffrement sans Secrets

Je suggère de tout supprimer après "La bonne manière". La proposition de Coda Hale présente un certain nombre de faiblesses. Il fait plusieurs erreurs que j'ai documentées dans d'autres réponses ici: il utilise le cryptage sans authentification de message (une faille grave), il crée la clé comme le hachage d'un mot de passe (une faille grave), il ne tente pas de ralentir la recherche exhaustive de clés (un autre défaut grave). Ma recommandation pour la bonne façon de gérer cela est décrite dans le dernier paragraphe de ma réponse intitulé "Ne roulez pas votre propre crypto".
Je suggère de supprimer tous les éléments après "Avertissement" et "Quelques faits saillants". Je pense que la plupart d'entre eux ne sont pas pertinents pour votre point de haut niveau sur le fait d'éviter la BCE, et sont une distraction. Soyez concis. Au lieu de cela, je suggérerais que votre conseil pour la bonne manière devrait être: Utilisez un mode de fonctionnement sécurisé, tel que le mode CBC ou le mode CTR. N'oubliez pas de suivre les autres conseils de cette page, y compris l'utilisation de l'authentification des messages, la génération des clés de manière appropriée, etc. Si vous voulez en faire un wiki communautaire, je serais heureux de modifier cette réponse en conséquence.
@D.W. Oui, n'hésitez pas à modifier une ou toutes les réponses en CW. Je pense que je ne veux pas poser toute la question CW est d'encourager les affiches, mais je vais vous laisser cette décision. Je veux juste apprendre les bonnes choses et désapprendre les mauvaises pratiques
Notez que cette erreur est encore plus facile à faire en Java, qui utilise / ECB / PKCS5Padding par défaut (par exemple `Cipher.getInstance (" AES ")`), et si vous passez à CBC, il utilise un IV mis à zéro (plus ou moins un NONCE, voir la réponse à ce sujet) par défaut également.
Comment avez-vous chiffré l'image comme ça ??
@Matt, cette image est le résultat d'une attaque réussie. Étant donné un fichier nommé TUX.BMP, supposons que l'attaquant essaiera de le regarder mais découvre qu'il est chiffré. Il visualise ensuite les octets cryptés et, en voyant un modèle non aléatoire, il suspecte CBC. Il remplace ensuite les deux premiers blocs par un bon en-tête de fichier BMP connu, et le peaufine jusqu'à ce que les lignes et les colonnes s'alignent. J'ai vu un chercheur utiliser un outil pour faire cela chez Blackhat il y a quelques années, je pense que l'outil s'appelait rumint.
#7
+20
D.W.
2011-02-20 09:50:34 UTC
view on stackexchange narkive permalink

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

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

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

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

Est-ce que s / MIME fonctionne contre cette recommandation? AFAIK Je n'ai qu'une seule clé et j'ai la possibilité de signer et de crypter.
À mon humble avis, le plus gros problème lié à l'utilisation des mêmes clés pour les deux usages provient de problèmes d'application de la loi. Dans de nombreuses juridictions, vous pouvez désormais être invité à rendre vos clés de cryptage, ce qui signifierait en pratique qu'ils peuvent signer à votre nom.
Oui, de nombreux algorithmes utilisent la même paire de clés pour la signature et le chiffrement, PGP et S / MIME étant les exemples évidents. Ce n'est pas nécessairement un problème mathématique.
PGP n'utilise ** pas ** la même paire de clés pour la signature et le chiffrement. Au contraire, une clé privée PGP est composée d'une clé principale, utilisée pour la signature, et d'une ou plusieurs sous-clés, utilisées pour le chiffrement. Les sous-clés sont cachées à l'utilisateur, d'où la confusion, mais vous pouvez les visualiser en utilisant `gpg --list-secret-keys`.
#8
+17
Chris Dale
2012-06-25 16:46:15 UTC
view on stackexchange narkive permalink

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 que l'algorithme a été connu, il est maintenant très simple de le casser.

L'algorithme est le suivant ( depuis wikipedia):

  1. Le mot de passe ASCII de l'utilisateur est converti en majuscules.
  2. Ce mot de passe est complété par des valeurs nulles jusqu'à 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 clés DES, une de chaque moitié de 7 octets
  5. Chacune des deux clés est utilisée pour chiffrer DES la chaîne ASCII constante «KGS! @ # $%», ce qui donne 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 divisez facilement le texte chiffré en deux textes chiffrés que vous savez être en majuscules, ce qui donne un jeu limité de caractères que le mot de passe pourrait éventuellement être.

Un exemple correct: chiffrement AES

  • Algorithme connu
  • Échelle avec la technologie. Augmentez la taille de la clé lorsque vous avez besoin de plus de puissance cryptographique
#9
+13
curiousguy
2011-09-28 09:03:50 UTC
view on stackexchange narkive permalink

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 le hachage.
  • Ne réutilisez pas les clés.
  • Ne réutilisez pas les nonces.

Pendant un exécution du protocole cryptographique de nombreux messages qui ne peuvent être contrefaits sans secret (clé ou nonce) peuvent être échangés. Ces messages peuvent être vérifiés par le reçu parce qu'il connaît une clé publique (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 lors de la même exécution du protocole: un adversaire peut avoir capturé ces messages précédemment, ou pendant une exécution simultanée du protocole. Un adversaire peut lancer de nombreuses exécutions simultanées d'un protocole cryptographique pour capturer des messages valides et les réutiliser sans modification.

En rejouant intelligemment les messages, il peut être possible d'attaquer un protocole sans compromettre aucune clé primaire, sans attaquer aucun RNG , tout chiffrement, etc.

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

En fait, un nonce n'a pas besoin d'être un secret, il ne doit être utilisé qu'une seule fois (dans un certain laps de temps, par exemple la validité de la clé secrète correspondante).
@PaŭloEbermann De nombreuses utilisations d'un nonce ne nécessitent pas de secret, mais certains formalismes de protocole appellent le * secret * utilisé pour authentifier les messages un "nonce" plutôt qu'une clé, car il n'est pas utilisé comme clé de chiffrement.
#10
+13
D.W.
2011-02-20 11:39:43 UTC
view on stackexchange narkive permalink

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 de passe, ou un hachage d'un mot de passe ou d'une phrase de passe, comme la 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 est d'utiliser une clé de chiffrement / déchiffrement vraiment aléatoire, et non une clé généré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 / une phrase de passe, utilisez un schéma approprié pour ralentir la recherche exhaustive de clés. Je recommande PBKDF2, qui utilise le hachage itératif (dans le sens de H (H (H (.... H (mot de passe) ...)))) pour ralentir la recherche dans le dictionnaire. Arrangez-vous pour utiliser suffisamment d'itérations pour que ce processus prenne, par exemple, 100 ms sur la machine de l'utilisateur pour générer la clé.

En tant que débutant, j'avoue avoir fait cela. Si la clé est aléatoire et donc impossible à mémoriser, recommandez-vous que les clés soient stockées quelque part sous une forme physique? C'est la seule façon que je vois d'implémenter un système avec des clés purement aléatoires.
@AdamCross, * "Si la clé est aléatoire et donc impossible à mémoriser, recommandez-vous que les clés soient stockées quelque part sous une forme physique?" * - Eh bien, stockées quelque part, elles peuvent être sous forme électronique ou physique. Le formulaire non électronique ne doit pas nécessairement être privilégié par rapport au formulaire électronique dans toutes les situations. Pour donner un exemple ... vous pouvez utiliser SSL pour vous connecter à un site Web en toute sécurité. La clé de session SSL que vous utilisez n'est stockée nulle part sous forme non électronique et n'est pas dérivée d'une phrase de passe.
haha pour clarifier, par "forme physique", je veux dire un endroit autre que ma tête --- mais cela n'a pas vraiment de sens puisque ma tête est aussi physique.
#11
+8
D.W.
2011-02-20 09:48:24 UTC
view on stackexchange narkive permalink

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 comme pour la direction B-> A. C'est une mauvaise idée, car cela permet souvent de rejouer des attaques qui rejouent quelque chose A envoyé à B, retour à A.

L'approche la plus sûre est de 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.

Ou vous pourriez avoir un SSC, un compteur de session sécurisé, augmenté pour chaque cryptage (dans la communication semi-duplex). J'ai même vu un exemple où le dernier bloc de texte chiffré de l'autre partie a été utilisé comme IV pour le bloc suivant, mais cela pourrait conduire à des attaques particulières.
@owlstead, Oui, l'utilisation du dernier bloc de texte chiffré comme IV pour le bloc suivant, avec le mode CBC, a conduit à l'attaque BEAST contre SSL. P.S. Un SSC pourrait travailler pour séparer les deux canaux, mais vous devrez y faire attention. Vous devrez l'incrémenter à la fois pour l'envoi et la réception (l'utilisation de deux SSC, un pour chaque direction, irait à l'encontre de l'objectif). De plus, le SSC exigera que les deux côtés soient synchronisés et ne tolérera pas les abandons de paquets, ce qui peut être problématique dans certains contextes. Il peut être plus facile d'utiliser simplement deux touches indépendantes.
Intéressant, je connais certaines cartes mémoire qui utilisent ce schéma avec la dernière partie du bloc de chiffrement comme IV pour la suivante. Je vais l'examiner. Merci D.W.
Cela ouvre également la porte à une attaque à deux temps, ce bit Microsoft PPTP. La première version de PPTP utilisait la même clé dans le client et le serveur
#12
+8
D.W.
2011-02-20 09:44:44 UTC
view on stackexchange narkive permalink

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 ' d recommande 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 les amateurs, simplement en essayant de manière exhaustive toutes les clés possibles. N'utilisez pas de DES 56 bits; ce n'est pas anodin de casser, mais il est à la portée d'attaquants dévoués de casser DES. Un algorithme de 128 bits, comme AES, n'est pas sensiblement plus lent qu'un crypto 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 le niveau de sécurité requis. De plus, l'augmentation de la taille de la clé nuit aux performances, donc une surpuissance massive n'est pas économique; ainsi, cela nécessite un peu plus de réflexion que la sélection des tailles de 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 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 1536 ou même 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 consulter les directives publiées établissant des équivalences approximatives entre les tailles de clé symétrique et de clé publique.

Le NIST recommande plus de clés 1024 bits à la fin de 2010: http://securitymusings.com/article/1587/algorithm-and-key-length-deprecation
Seule phrase avec laquelle je ne suis pas d'accord: "C'est une erreur moins courante de nos jours" "... Toujours l'une des erreurs de cryptage les plus courantes que je vois, après" Pas de cryptage "et" Rouler votre propre crypto ".
@AviD, @nealmcb, merci pour vos commentaires. J'ai modifié pour refléter le commentaire d'@AviD's. Notez que j'en ai fait un wiki communautaire, alors n'hésitez pas à le modifier pour améliorer les recommandations et corriger les erreurs.
#13
+3
Shane Hansen
2012-09-08 21:55:43 UTC
view on stackexchange narkive permalink

Utilisez le mode correct

De manière équivalente, ne vous fiez pas aux 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 appelé mode ECB (Electronic Code Book), qui est essentiellement un mappage simple de:

  AES (clairxt [32 ] octet, clé [32] octet) -> texte chiffré [32] octet  

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

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

  ciphertext [i] = SomeFunction (texte chiffré [i-1], message [i], clé)  

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

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

OpenSSL, fait cela correctement. Chaque appel AES est explicite sur le mode de fonctionnement. Vraiment, la chose la plus sûre IMO est d'essayer de ne pas faire de crypto de bas niveau comme celle-ci vous-même. Si vous y êtes obligé, 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.

Merci pour cette réponse, Shane! Une question: est-ce déjà couvert par l'autre réponse [N'utilisez pas de chiffrement par bloc avec ECB pour le chiffrement symétrique] (http://security.stackexchange.com/a/2203/971)?
#14
+3
D.W.
2012-10-17 19:57:20 UTC
view on stackexchange narkive permalink

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

Plus vous partagez une clé cryptographique, moins vous serez en mesure de la conserver secret. Certains systèmes déployés ont réutilisé la même clé symétrique sur tous les périphériques du système. Le problème avec cela 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 faites pas cela.

Voir aussi «Le chiffrement symétrique à ne pas faire n ° 6: ne partagez pas une seule clé sur plusieurs appareils» dans cet article de blog. Crédits à Matthew Green.

#15
+3
John Deters
2013-05-15 22:04:48 UTC
view on stackexchange narkive permalink

Un pad ponctuel n'est pas un pad ponctuel si la clé est étirée par un algorithme

L'identifiant "one-time pad" (é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ériel clé est vraiment imprévisible; AND
  • Le matériel clé a la même longueur que le texte brut; AND
  • Le matériel clé n'est jamais réutilisé.

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

L'erreur commune commise 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 que cela est fait, le pavé à usage unique est mathématiquement transformé en algorithme d'étirement de clé. 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 de clé. De même, l'utilisation d'octets "générés aléatoirement" 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 à l'aide d'un "pad à usage unique" qui utilise une fonction cryptographiquement sécurisée comme générateur de clé. J'ai choisi une clé secrète, puis j'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.

  texte en clair: 1234567890123456789012345678901234567890 matériel clé: 757578fbf23ffa4d748e0800dd7c424a46feb0ccOTP function (xor) ------ texte chiffré: 67412E83622DCE1B0C1E1A348B04D25872A8C85C  

Le matériel clé a été généré en toute sécurité en utilisant 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 XORing la sortie avec le texte chiffré. Deviner la clé "OTP" n'est désormais pas 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 contient ou la manière dont il est implémenté ou amorcé.

Vous pouvez avoir un très bon algorithme d'étirement des touches. 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 pad ponctuel, et n'a donc pas la propriété incassable d'un pad ponctuel.

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

Souhaitez-vous éditer "" 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. " EXEMPLE: un double time pad, un mauvais protocole ou un autre biais (PPTP, WEP, RC4 respectivement). Un profane inconnu peut mal interpréter ce que vous avez écrit et penser que le Bureau du Procureur offre un "secret parfait" dans un autre sens du terme. De plus, puisque vous abordez ce sujet, une couverture de ce qu'est une civière de clé PNG / PRG valide serait utile.
Remarque: il n'y a pas d'authentification de message dans un OTP. Les modifications apportées à un OTP ne seront pas détectées.
Remarque: Un * PRG sécurisé * est similaire à un OTP. C'est celui qui a tous les tests statistiques efficaces avec un résultat négligeable, et qu'il est impossible pour un PRG de satisfaire tous les tests statistiques théoriques. Ce "relâchement" de la sécurité est nécessaire pour l'efficacité puisque "Perfect Secrecy" nécessite une transmission sécurisée d'un OTP suffisamment grand pour correspondre à la taille du message. EXEMPLE: Toutes les transmissions OTP nécessitent que le secret soit transmis en toute sécurité (ce qui n'est pas défini comment). Il est plus efficace d'utiliser cette méthode sécurisée pour envoyer les données en premier lieu.
C'est la «similitude» qui conduit les gens à faire des déclarations farfelues d'incassabilité, et c'est cette «efficacité» qui brise l'imprévisibilité du chiffre de Vernam. Personne n'a dit que la génération de clés, la gestion des clés ou la distribution de clés avec un OTP était facile ou pratique - ce n'est rien de tout cela. C'est tellement difficile que les gens utilisent encore d'autres cyphers, malgré la promesse d'un secret mathématiquement parfait. Aucun «étirement des clés» ne peut altérer cette vérité.
Un "PRNG sécurisé" pourrait être utilisé pour générer les bits, mais s'il est vraiment sécurisé, vous avez toujours tous les problèmes de distribution car vous ne pouvez pas dupliquer leur génération sur l'ordinateur du destinataire - si vous le pouviez, cet état serait la clé, pas le morceaux.
#16
+1
Watson Ladd
2012-09-08 21:05:27 UTC
view on stackexchange narkive permalink

Ne faites pas confiance aux normes.

De nombreuses normes existent en cryptographie, et parfois vous devez les utiliser. Mais ne supposez 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 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é. La puce et le code PIN ont été cassés à plusieurs reprises à plusieurs reprises, grâce à une abondance de caractéristiques dangereuses. GPG prend toujours en charge les clés DSA trop courtes pour le confort. SSL a des options qui ne doivent pas être utilisées, et nécessite des précautions pour les éviter.

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

MD5 est un standard, c'est vrai. Mais il a été remplacé par une norme plus actuelle, SHA. Pour la plupart des scénarios, les normes DEVRAIENT être suivies pour de nombreuses raisons. L'interopérabilité est un facteur très important.
C'est une déclaration très trompeuse. Le libellé implique que le lecteur doit "faire confiance aux NON-standards", ce qui n'est clairement pas vrai. La plupart des normes de sécurité n'entrent en vigueur qu'après des tests approfondis sur le terrain. Ces tests sont beaucoup plus approfondis que n'importe quelle organisation ne peut générer pour «prouver» que leur système non standard est sécurisé.
#17
+1
goodguys_activate
2013-05-20 20:47:19 UTC
view on stackexchange narkive permalink

N'utilisez pas de chiffrement OTP ou de flux dans le chiffrement du disque

Exemple 1

Supposons que deux fichiers soient enregistrés en utilisant 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 en déduire des informations sur le document. (Imaginez changer la salutation «Cher Bob» en «Cher Alice»).

Exemple 2

Il n'y a pas d'intégrité dans le résultat: un attaquant peut modifier le texte chiffré et modifier le contenu des données en effectuant simplement un XOR sur les données.

À retenir: 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

#18
  0
goodguys_activate
2013-05-20 21:08:44 UTC
view on stackexchange narkive permalink

Ne jamais utiliser une clé de chiffrement One Time Pad (OTP) ou de flux plus d'une fois

Un OTP appliqué deux fois signifie que les données chiffrées avec le "secret parfait" seront déchiffrées et en clair. Cela se produit parce que les données sont XOR'ed deux fois.

Example↑

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

Un attaquant collecte beaucoup de données envoyé d'un client à un serveur, et XORs un ensemble de deux paquets ensemble jusqu'à ce que les deux paquets se déchiffrent (ou sous-ensemble à l'intérieur).

Le codage ASCII a une redondance suffisante pour que, avec suffisamment de texte chiffré, les messages originaux pourraient être décodés (avec la clé secrète OTP).

Exemples du monde réel

  • Projet Verona (1941-46) pour un exemple d'un OTP utilisé par les Russes et a été par la suite 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 a une longueur de 24 bits, ce qui signifie qu'après 16 millions de trames transmises, un tampon à deux 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 réinitialise à zéro, ce qui entraîne un décalage de deux heures. Ce problème est facile à voir puisque l'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 devrait utiliser une 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 d'étendre une seule clé dans un long flux en utilisant un PRG (en supposant que vous faites confiance au PRG) et utilisez chaque segment de cette expansion comme clé.

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

#19
  0
goodguys_activate
2013-05-20 21:26:00 UTC
view on stackexchange narkive permalink

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 [2nd byte = 0] = 2/256
  2. La probabilité de seize bits égal à zéro est 1/256 ^ 2 + 1/256 ^ 3. Cela se produit après le chiffrement de plusieurs Go de données.
  3. Vulnérable aux attaques par clé associées, où seul le IV change mais la clé reste la même.

À emporter Si vous devez utiliser RC4, ignorez les 256 premiers octets car ils sont biaisés. Si vous utilisez RC4 pour des Gigs de données, alors le biais de RC4 permettra d'attaquer toutes les données cryptées précédentes.

#20
  0
goodguys_activate
2013-05-20 21:49:46 UTC
view on stackexchange narkive permalink

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. Le registre à décalage de 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 être fiables pour les communications sécurisées.

Attaque:

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

Voici à peine nouveau, mais le logiciel libre est facile à trouver, ce qui illustre ce problème.

Solution:

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

À part

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

  Vitesse PRG (Mo / s) RC4 126 (obsolète) Salsa20 / 12 643 (moderne) Sosemaunk 727 (moderne)  
#21
  0
goodguys_activate
2013-05-23 09:42:28 UTC
view on stackexchange narkive permalink

N'utilisez que 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'une plaine donnée texte. De nombreuses implémentations et normes publiées ne parviennent pas à protéger un MAC d'un attaquant qui ajoute des données supplémentaires au MAC.

La solution pour cela 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 chiffrements qui empêchent correctement le attaque par extension de message.

Solution:

  • Utilisez CBC crypté (ECBC) au lieu de CBC brut
  • Utilisez NMAC au lieu de cascade


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 2.0 sous laquelle il est distribué.
Loading...