web-dev-qa-db-fra.com

Existe-t-il un exemple simple de routine de chiffrement / déchiffrement asymétrique?

Je peux très bien comprendre le code Java, Perl et JavaScript. Le reste, je n'ai pas étudié, mais je suppose que je pourrais trouver comment lire/traduire.

Je voudrais savoir quelles sont les routines asymétriques les plus simples. Est-ce vraiment trop complexe de vouloir s'inquiéter?

Je suis vraiment curieux de savoir comment il est possible d'avoir une clé de chiffrement uniquement! Il me semble juste qu'il puisse résister à la rétro-ingénierie, donc je veux savoir comment ça marche!

  1. C'est trop compliqué pour ça.
  2. Quelle est (une des) routine (s) de chiffrement asymétrique standard la plus simple pour laquelle je peux rechercher une implémentation?
  3. Si vous avez des exemples de code minimal, ce serait bien.

J'ai déjà vérifié le paragraphes Wikipedia sur le fonctionnement , mais il n'y avait pas de ventilation mathématique ou de description de l'implémentation, juste beaucoup d'implémentations . Je ne voulais pas vraiment choisir celui à regarder au hasard, je ne voulais pas non plus prendre le plus commun qui, je pense, est le plus robuste et le plus compliqué.

Des pensées?

11
Bryan Field

Nous remercions réponse de Jeff pour les détails et réponse de Steve qui a également été utile. Le crédit revient également à réponse de tylerl qui comprenait des liens vers Wikipedia pour toutes les fonctions, en particulier modInverse , il a également clarifié le point de départ ambigu pour e. Merci, J'ai voté pour vos réponses, et en utilisant les informations combinées des trois réponses, j'ai créé ce que j'espère être une meilleure réponse.

La clé pour rendre la rétro-ingénierie si chère est d'utiliser la puissance de . La racine carrée n'est pas si dure, une puissance de 3 signifie que vous avez besoin d'une racine cubique, mais une puissance de 34 051 489 est assez difficile. Il existe d'autres opérations mathématiques qui sont difficiles à rétroconcevoir. Il existe également plusieurs façons de créer un algorithme asymétrique, mais cette réponse se concentre sur RSA. Le plus ancien et le plus courant.

Algorithme RSA (basé sur le Java Code )

Les calculs ci-dessous doivent être effectués avec entiers de précision arbitraires . (Tels que BigInt ou BigInteger)

Génération des clés:

  • La longueur de clé constante est l.
  • Habituellement constant e_start Peut =3 Pour plus de simplicité. Cependant, 0x10001 Est plus courant, en tout cas, un nombre premier est le meilleur (pour des raisons de performances de génération de clés et probablement d'autres raisons).
  • p et q sont les nombres premiers positifs générés aléatoirement, qui nécessitent jusqu'à l bits pour le stockage. (Pour les garder positifs, le premier bit sera toujours 0)
  • n = p*q Ceci est utilisé pour le chiffrement et le déchiffrement.
  • e commence comme e_start. Ce sera finalement la partie de la clé de cryptage.
  • m = (p-1)*(q-1) est utilisé pour convertir e en d, qui sera utilisé pour le décryptage.
  • while(gcd(e,m)>1){e+=2} Ceci est nécessaire pour que la prochaine étape fonctionne.
  • d=modInverse(e,m) Ceci effectue une opération arithmatique standard. Il ne vaut probablement pas la peine d'être examiné beaucoup, surtout si votre langage de programmation a ce

Pour chiffrer ou déchiffrer, convertissez d'abord vos octets en un seul entier de précision arbitraire.

Cryptage: encrypted=(plain^e)%n

Remarque: Si plain>=n, Vous devez diviser plain en deux ou plusieurs valeurs plus petites et les chiffrer séparément.

Décryptage: plain=(encrypted^d)%n

Le chiffrement asymétrique est généralement moins efficace que le chiffrement symétrique. Parfois, le cryptage asymétrique est utilisé uniquement pour l'échange de clés.

6
Bryan Field

En ce qui concerne RSA, this fournit un bon exemple qui peut être suivi et montre des exemples correspondants d'entrée et de sortie. Cette application démo vous guidera à travers les différentes étapes et vous permettra de vérifier le travail. Parfois, il suffit de cliquer sur votre chemin à travers quelque chose comme cela vous aidera. Pour les articles Wikipedia, vous devez regarder l'article réel de l'algorithme: RSA pour les mathématiques qui correspondent.

En ce qui concerne l'implémentation, vous pouvez rassembler cela clairement dans Java in moins de 30 lignes .

Pour votre compréhension, il n'existe pas de clé de chiffrement uniquement. Il existe plutôt deux clés égales qui inversent les opérations de leurs partenaires. Nous attribuons arbitrairement l'un de la paire comme privé et un comme public. Les objets chiffrés avec une clé peuvent être déchiffrés avec l'autre clé. C'est le principe utilisé avec la signature.

Ce n'est pas un problème d'ingénierie anti-reverse qui sécurise les clés, mais plutôt un concept mathématique selon lequel vous ne pouvez pas raisonnablement vérifier l'espace de clés massif (lorsque la clé utilise un espace de nombres très grand) pour trouver la clé correspondante. Il n'y a pas de véritable accélération pour le travail d'affacturage.

Il existe d'autres algorithmes de clés asymétriques à apprendre, mais en regardant fixement, j'essaierais d'abord de comprendre RSA, le plus ancien et le plus courant.

13
Jeff Ferland

J'ai mis en place une démonstration de RSA en utilisant python (python est très facile à lire même si vous ne l'avez jamais vu auparavant). Le code est suffisamment long pour ne pas tenir sur un seul page, mais suffisamment courte pour que vous puissiez la lire et la comprendre en quelques minutes.

Étant donné que le chiffrement/déchiffrement peut être accompli dans une seule commande intégrée - exp(PLAINTEXT,KEY,MODULUS) - je passe également par tout le processus de dérivation de clé.

Vous trouverez le code ici: https://Gist.github.com/1239116

Lorsque vous exécutez le code, il vous demande de le saisir sous la forme de >12345 ou <12345, où le > le préfixe lui indique d'appliquer la clé privée au numéro, tandis que < lui dit d'appliquer la clé publique. Dans un souci de simplicité, il code uniquement les nombres; mais une fois que vous avez cela, l'encodage de données arbitraires n'est qu'une question de formatage.

6
tylerl

En fait, le calcul est assez simple, si je comprends bien. Vous prenez une valeur à la puissance d'un nombre premier extrêmement grand (des milliers de chiffres) et faites un mod à partir d'un autre nombre.

Donc, pour crypter, vous avez quelque chose comme: EncryptedBits = (PlainText ^ YourPublicKey)% Modulus

Et pour décrypter, vous avez quelque chose comme: PlainText = (EncryptedBits ^ YourPrivateKey)% Modulus

Je suis tombé sur un document assez facile à lire ici: http://mathaware.org/mam/06/Kaliski.pdf

Je ne suis pas sûr de savoir quelles bibliothèques regarder.

5
Steve

Si vous voulez une solution Perl mignonne et minimale, il y en a une classique par Adam Back de 1995 :

Il a été imprimé sur un t-shirt, y compris un code-barres pour le rendre lisible par ordinateur, avec la mention " Ce T-shirt est une munition " . Cette déclaration était exacte aux États-Unis avant que la cryptographie forte ne soit reclassée en 1996 pour ne plus être techniquement une "munition". Mais il était encore largement interdit d'exporter une cryptographie forte des États-Unis jusqu'à ce que les Export Administration Regulations (EAR) soient révisées en 20 :

Le logiciel a également été distribué sous forme de tatouage, de signature électronique, d'étiquette de publipostage et sous de nombreuses autres formes, et est même apparu (sous forme floue) dans le New York Times (l'article, sans la photo, est en ligne sur Entre un pirate informatique et un endroit dur ). Une version 2 lignes plus récente est:

print pack"C*",split/\D+/,`echo "16iII*o\U@{$/=$z;[(pop,pop,unpack"H*",<>
)]}\EsMsKsN0[lN*1lK[d2%Sa2/d0<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<J]dsJxp"|dc`

Notez que l'approche originale repose sur le programme "dc" Unix pour une arithmétique de précision arbitraire. Une version pure-Perl, avec annotation, est à

2
nealmcb