Cryptographie en langage simple: nous analysons le cryptage symétrique et asymétrique en utilisant l'exemple de l'intrigue Star Wars (Mise à jour)

Bonjour à tous les lecteurs de Habr! Il n'y a pas si longtemps, j'ai décidé de m'occuper des algorithmes de chiffrement et des principes de la signature électronique. Le sujet, je pense, est intéressant et pertinent. En train d'étudier, j'ai essayé plusieurs bibliothèques, mais la bibliothèque PyCrypto est la plus pratique de mon point de vue. Elle a une excellente documentation, accompagnée d'exemples.

image

Après avoir lu le matériel, vous apprendrez les points suivants:

  1. Qu'est-ce que le chiffrement;
  2. Quelle est la différence entre un chiffrement symétrique et asymétrique;
  3. Dans ce cas, il est plus efficace d'utiliser symétrique et dans quel chiffrement asymétrique;
  4. Qu'est-ce qu'un hachage de données et pourquoi est-il utilisé dans le chiffrement?

La pertinence du sujet est en constante augmentation. L'utilisation de la cryptographie ne se limite pas depuis longtemps au cryptage des informations. Sous une forme ou une autre, nous utilisons tous les jours des algorithmes de cryptage lors de la visite des sites via le protocole HTTPS, lors des achats par carte bancaire et lors de la communication via les messageries instantanées. Au cours des dernières années, les technologies de la chaîne de blocs, également basées sur la cryptographie, ont attiré une large attention.

Le but de cet article est d'initier le lecteur aux algorithmes de chiffrement de base. Lors de la rédaction d'un article, j'ai essayé d'accorder autant d'attention que possible à la question de l'application pratique. Pour la programmation, Python 3.6 a été utilisé. Lors de l'écriture du code, j'ai essayé de le diviser en parties distinctes et de commenter tous les points clés.

Dans cet article, je n'ai pas analysé la signature numérique, mais après avoir compris le cryptage asymétrique, le sens de cette technologie deviendra clair.

Terrain


Voyons mentalement dans l'univers de Star Wars avant les événements de l'épisode 6, lorsque les forces de résistance prennent conscience du début de la construction d'une nouvelle étoile de la mort. Le commandement prévoit d'introduire un groupe de renseignement sous le couvert de constructeurs. L'opération est très dangereuse, la communication avec le siège sera difficile. En cas de situation d'urgence, chaque membre du groupe peut envoyer et recevoir des messages du siège à une fréquence non protégée.

Le but du groupe de reconnaissance est toute donnée pouvant éclairer la configuration, les armes et le but de la future station. Pour stocker les données, il est prévu de développer des équipements et logiciels spéciaux.

Le siège a approuvé deux options pour cette opération:

Plan A - Retour d'agents avec des forces rebelles données;
Plan B - transmission à distance des plans de l'étoile de la mort elle-même en utilisant l'équipement de la station. Le transfert d'informations sera rapide, mais après le transfert, l'agent est le plus susceptible d'être calculé et capturé.

Schéma
image

Vous êtes programmeur dans une équipe responsable du développement logiciel.

Lors de la planification d'une opération, plusieurs scénarios négatifs possibles sont pris en compte:

  • L'ennemi va intercepter le signal, comprendre son contenu sur la planification de l'attaque et rapprocher l'objet des forces fidèles à l'Empire. Dans ce cas, les pertes parmi la résistance seront plus importantes;
  • L'un des espions sera capturé et révélera au cours de l'interrogatoire le plan d'opération, ce qui peut conduire à la compromission des clés de chiffrement (nous en parlerons plus loin);
  • Un espion avec des données téléchargées peut être intercepté par les forces impériales, qui apporteront des modifications au contenu, mal informant la résistance sur les faiblesses de la station. Dans ce cas, lors de l'attaque, la flotte rebelle sera envoyée dans une fausse direction et progressivement détruite;

À partir de ces scénarios, les tâches sont formulées:

  1. Le contenu doit être crypté en toute sécurité et protégé contre les modifications;
  2. En cas de perte de clés de chiffrement ou de leur compromission, il devrait être possible d'obtenir de nouvelles clés de chiffrement à distance à une fréquence pouvant être exploitée par l'adversaire.

Cryptage des informations


Résolvons le problème du cryptage des informations:

Une clé de cryptage est utilisée pour crypter et décrypter des informations. C'est la clé qui rend le chiffrement réversible. Chaque agent recevra une clé de cryptage. Après avoir téléchargé les données, l'agent les chiffrera et les enverra au siège de la résistance.

Description du principe de cryptage
La méthode dans laquelle le message est chiffré et déchiffré à l'aide d'une seule clé est appelée chiffrement symétrique .

image

Le point faible du cryptage symétrique est la clé de cryptage, ou plutôt sa remise au destinataire. Si la clé est compromise lors de la remise, un tiers peut facilement décoder le message. La force du chiffrement symétrique est sa vitesse, qui permet de coder de grandes quantités de données.

Le chiffrement asymétrique utilise deux clés connectées l'une à l'autre: publique et privée.

image

Le mécanisme d'action est le suivant:

  1. le destinataire envoie la clé OUVERTE à l'expéditeur;
  2. l'expéditeur code le message à l'aide de la clé publique reçue. Dans le même temps, le message ne peut désormais être décodé qu'avec la clé privée;
  3. à la réception du message crypté, le destinataire le décode avec la clé CLOSED (qui a été générée en tandem avec le public).


Commençons par la programmation! Pour développer le logiciel nécessaire, nous utiliserons la bibliothèque Python appelée pycrypto . Elle possède une excellente documentation et présente tous les algorithmes de chiffrement courants.

Tout d'abord, nous allons développer une fonctionnalité de chiffrement symétrique appelée Advanced Encryption Standard (AES) . Il s'agit de l'un des algorithmes de chiffrement symétrique les plus courants.

from Crypto.Cipher import AES #   from Crypto.Hash import SHA256 #        SHA. from Crypto.Hash import MD5 #            32  from Crypto import Random def transform_password(password_str): """Transform the password string into 32 bit MD5 hash :param password_str: <str> password in plain text; :return: <str> Transformed password fixed length """ h = MD5.new() h.update(key.encode()) return h.hexdigest() def symmetric_encrypt(message, key, verbose = True): """Encripts the message using symmetric AES algorythm. :param message: <str> Message for encryption; :param key: <object> symmetric key; :return: <object> Message encrypted with key """ key_MD5 = transform_password(key) #      32  message_hash = SHA256.new(message.encode()) message_with_hash = message.encode() + message_hash.hexdigest().encode() #     .      iv = Random.new().read(AES.block_size) cipher = AES.new(key_MD5, AES.MODE_CFB, iv) #     . AES.MODE_CFB -   ,      iv. https://www.dlitz.net/software/pycrypto/api/current/Crypto.Cipher.blockalgo-module.html#MODE_CFB encrypted_message = iv + cipher.encrypt(message_with_hash) #       .  ,       ,       . if verbose: print(f'Message was encrypted into: {encrypted_message.hex()}') return encrypted_message def symmetric_decrypt(encr_message, key): """Decripts the message using private_key and check it's hash :param encrypted_message: <object> Encrypted message :param key: <object> symmetric key; :return: <object> Message decripted with key """ key_MD5 = transform_password(key) #   ,      bsize = AES.block_size dsize = SHA256.digest_size*2 iv = Random.new().read(bsize) cipher = AES.new(key_MD5, AES.MODE_CFB, iv) decrypted_message_with_hesh = cipher.decrypt(encr_message)[bsize:] #     ,      decrypted_message = decrypted_message_with_hesh[:-dsize] #   ,      digest = SHA256.new(decrypted_message).hexdigest() #    .     ,     . if digest==decrypted_message_with_hesh[-dsize:].decode(): #      ,      ,   print(f"Success!\nEncrypted hash is {decrypted_message_with_hesh[-dsize:].decode()}\nDecrypted hash is {digest}") return decrypted_message.decode() else: print(f"Encryption was not correct: the hash of decripted message doesn't match with encrypted hash\nEncrypted hash is {decrypted_message_with_hesh[-dsize:]}\nDecrypted hash is {digest}") 

Vérifions les performances du code à l'aide d'un exemple
 message = """  120   120  / 120   10     30-5 (2)    4.0 """ key = 'Traveling through hyperspace ain't like dusting crops, farm boy.' encr_message = symmetric_encrypt(message, key, verbose = True) print('\n') print('DECRIPTION') decr_message = symmetric_decrypt(encr_message, key) print(decr_message) 

 Message was encrypted into: ed10e4c65358bb9e351c801c3b3200b21fa86a24021c317bb5c9d8b3f76bdf9f3a7d26781a22402f0e4f41ca831b6d2da9e1e6878c34c79ddc7959af3ae9fc2ba0cfff1c0180a7e0f637f1aa5b24507d552d5dfe7625e7b81d817b5882b2b19bb95f3988a03c78f850098dfc8e6089863deaa39b887eaea4c1d4ba006edaec90205d54b27ed4ac70ed75cdd01732e1176bf04218beb8ae742ff708a201a9d1cb57dd5f2e70dc3239208d23705f7a3aae3e315c4df6d73c871b66c4995cce5f19738f731cd58755d21ed92612c44197f875cddf3f7aa1d60e435ce1492679b9d60c4b8538f52408f321711ac1d2daa6dbbc33dc655abca10e2f5fd3ff27823995b9dcdb62c0bafc1963ab539ccb466f1c140479df34b0005f578f72fcdd76b17391332037b801f74f733a08 DECRIPTION Success! Encrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026 Decrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026  120   120  / 120   10     30-5 (2)    4.0 Le Message was encrypted into: ed10e4c65358bb9e351c801c3b3200b21fa86a24021c317bb5c9d8b3f76bdf9f3a7d26781a22402f0e4f41ca831b6d2da9e1e6878c34c79ddc7959af3ae9fc2ba0cfff1c0180a7e0f637f1aa5b24507d552d5dfe7625e7b81d817b5882b2b19bb95f3988a03c78f850098dfc8e6089863deaa39b887eaea4c1d4ba006edaec90205d54b27ed4ac70ed75cdd01732e1176bf04218beb8ae742ff708a201a9d1cb57dd5f2e70dc3239208d23705f7a3aae3e315c4df6d73c871b66c4995cce5f19738f731cd58755d21ed92612c44197f875cddf3f7aa1d60e435ce1492679b9d60c4b8538f52408f321711ac1d2daa6dbbc33dc655abca10e2f5fd3ff27823995b9dcdb62c0bafc1963ab539ccb466f1c140479df34b0005f578f72fcdd76b17391332037b801f74f733a08 DECRIPTION Success! Encrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026 Decrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026  120   120  / 120   10     30-5 (2)    4.0 


Comme vous pouvez le voir, nous avons réussi à chiffrer le message à l'aide de la clé publique.
Exécutez le code plusieurs fois. Vous verrez que chaque fois que la partie chiffrée change. En effet, lors du chiffrement, nous avons utilisé le mode Cipher FeedBack (AES.MODECFB), dans lequel les blocs de texte en clair sont mélangés avec les blocs de texte chiffré. iv - vecteur d'initialisation (en savoir plus sur le mode ici ). Lors du décryptage du message, nous voyons que le hachage du message décrypté correspond au hachage que nous avons ajouté lors du cryptage. Cela signifie que le déchiffrement était correct.

Qu'est-ce qu'un hachage
Un hachage de document est simplement une chaîne de caractères unique à tout ensemble de données. Avec tout changement de données, le hachage change beaucoup. En d'autres termes, un hachage est une sorte «d'empreinte digitale» pour tout ensemble de données.



Mais que se passe-t-il si les clés de chiffrement sont compromises pour une raison quelconque? Ensuite, n'importe qui peut décrypter les informations.

Dans ce cas, nous devons en quelque sorte changer les clés de chiffrement à distance à une fréquence qui peut être exploitée par l'adversaire. Nous supposerons qu'ils l'écoutent déjà. Alors, comment faisons-nous cela? Ici, une autre méthode vient à la rescousse, appelée cryptage asymétrique (ou système cryptographique à clé publique). Contrairement au cryptage symétrique, il utilise deux clés: publique et privée. Le message est chiffré avec la clé publique, après quoi il ne peut être déchiffré qu'avec la clé privée. La clé publique de déchiffrement sera inutile. Cependant, il y a un point important: la clé privée doit certainement provenir de la paire publique générée. La présence d'une clé publique est l'une des nombreuses propriétés importantes et intéressantes du chiffrement asymétrique. Autrement dit, nous pouvons transmettre la clé publique par n'importe quel canal et ne pas avoir peur qu'elle soit utilisée pour décrypter le message.

En même temps, en ce qui concerne notre tâche, il y a une nuance - le chiffrement asymétrique convient aux petites données, par exemple les messages courts. Nous ne pouvons que deviner la quantité de données obtenues par l'intelligence. Bien sûr, nous pouvons diviser toutes les données reçues en petits fragments et les encoder chacune avec une clé privée, mais il existe une meilleure solution. (Le problème est réglé ici ).

Solution

L'utilisateur Akela_wolf a fait remarquer à juste titre que n'importe qui peut générer et envoyer la clé publique. J'ai apporté quelques ajustements au plan.

Il sera correct que, avant d'envoyer des agents, le siège social génère plusieurs paires de clés et attribue une clé privée à chaque agent. Il vaut mieux ne générer que quelques paires pour que chaque agent ait une clé individuelle. Cela est nécessaire pour personnifier avec précision le propriétaire de la clé.
Ensuite, si les clés sont compromises, le centre créera une nouvelle clé SYMMETRIC, la codera pour chaque agent avec des clés publiques et l'enverra sur le canal ouvert.
Schéma de solution général






Ancienne décision
  1. L'agent va générer une paire de clés (publique et privée) en place, puis envoyer la clé publique aux forces rebelles;
  2. Au siège de la résistance, ils créeront une nouvelle clé de cryptage SYMÉTRIQUE;
  3. La clé symétrique est codée à l'aide de la clé publique envoyée par l'agent;
  4. La clé symétrique chiffrée sera envoyée à l'agent, qui la décodera à l'aide de la clé privée.

Faites attention à notre émission sur la chaîne ouverte:

  1. L'agent envoie la clé OUVERTE de la paire, la clé FERMÉE est en sa possession;
  2. Le quartier général de la résistance envoie une clé de chiffrement symétrique, chiffrée avec la clé publique envoyée par l'agent.


Ni le premier ni le deuxième message n'ont de valeur dans l'interception.


Écrivons le code:

 #          RSA. #        SHA256 from Crypto.PublicKey import RSA #      def generate_keys(bits = 2048): """Generates the pair of private and public keys. :param bits: <int> Key length, or size (in bits) of the RSA modulus (default 2048) :return: <object> private_key, <object> public_key """ private_key = RSA.generate(bits) public_key = private_key.publickey() return private_key, public_key private_key, public_key = generate_keys(bits = 2048) 

Voyons à quoi ressemblent les clés.
 print(private_key.exportKey(format='PEM').decode()) print('\n') print('#'*65) print('\n') print(public_key.exportKey(format='PEM').decode()) 

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA4JDLu7Vtvg2yqbH6Y0eJPfoEsOlKzgmOodqhA1CqkEG4OpKi
sGW7ciGP4v37GE6edHBCEy4UNkVQtnpPBjzTHvKd1pO70B84vD5OSrS7uNw2EYkj
d/ZwhrJMrcQKRwPkkM4OiewaaAaK0vPWJIKwlW61DY9X7LfNz7aOKMTbKnm1vdR0
919AV98FUmNoQBgka6nXFGmNbi7D43MtLwxBZIXfFupEiANSvOs+57hgaCho7OWM
GUOjLkG6HBscPhJ2W1H5DU9GjwL24ynTvKifgo1/2ue61MV1Pzh5CVaicJKNaRtg
Pd99gFhBGINsXV2X6Jh/W5nNsCddU4EI0AlO8wIDAQABAoIBAARM4YnjrIlSK9Sy
EtBp40frjMFyhjsx1ahlzmWI2utORt/gRPtJx3AlEmNPZ8qMXt5t8+X4IOz1INmN
uAuviH90N++O/q66mlSIgOlPUrT0ipiFXseCUZ9StMMzGNtJSMw5FfAwNEU/stLd
VoF2ezkxWIg88XsX/fn3Tfub4XKLvu4raJGcJ+Fo2GI9hYEGKnHhSuHvDHekTLlQ
z46O+cIwtehbFGcKesyK3zDD1uP5YLPIWpiqt1TgKjJzRF0l4ZJLk+RT7kU2pGIQ
mosOnr+06WyMIg724yQyAIwtS9X0czKBGUESrtTTb1HCXLeTwnncOTxh6q2z42LF
tn34+DECgYEA6EEp4oTvjfTQfUQPMByuAjF1hpdFHQqRymygiFgoF+Mg3QmL0w8j
/84H/q7s8FSx+3th8MK87bFq4lrry+h/mYwmvF5zZbhxcnl2uaX+KUPgpT6TgvAo
WOv2wc4BSaoo9DrxrZId86vpO2qbopw6gkBsvw47HSoQ+FSqXtZ0p8kCgYEA94Zj
b1ulctUjybiszO93TAjkzx3lU3yL+B1eZiQXtJa3mgG+ka1R/uMfr0NlT+Jzo0My
wHV30YRJDxziCrDol9OgSSU0sXwEcUxUIBLBwXLCp1EmMsYG9PB/x4OTWve35a8F
O+rMxuvWaZeIOfVCfL8UEcWweYaVdWIonJN+ltsCgYEAjeSZ2UlMLZce9RjqioNL
EA31dlfeoqJ9dYUuAn6RaB6cSk51vWlnnfXazo9CNIYaAsFbkcL3t+QHn+jaXEZc
BowocjbmG4Q20zBAB6XRBJbynSIA7yMYE1N9+uOHx+CMisGkO12krOUfZex4zzzR
RhhkF8ly9htoKL9ZIv20YXkCgYBzH3UF6PkVZJ5lhtgP5Nx2Z7iLwBrV7ppnBrnO
BcFkw6iXH3KT7KmzQ82LxWvMcMVZzLpBGyFkOAOG3OchE9DKNKpa+sv8NHMYguip
li+5mneAPFTozoOTznuPvtl9OLO2RuXHTVh6uFub9tdsJW8L+A8MiQagLwE6fDHp
SQxaewKBgQDIyzL1THpW3+AMNrOZuI/d3Em5wpGJiZbDSBRosvsfGm/sHaz4Ik5E
nWnftgktmsAD60eORTTh9/ww/nm7f3q9kzT8Sv1MmqeRXq9VFIOeP/+8SSE/7LzD
izlb5xEtVD8LuY54jHyiOxiZC++TQswMnOKKi0Gx26MDoO7Tx9akVw==
-----END RSA PRIVATE KEY-----

#################################################################

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4JDLu7Vtvg2yqbH6Y0eJ
PfoEsOlKzgmOodqhA1CqkEG4OpKisGW7ciGP4v37GE6edHBCEy4UNkVQtnpPBjzT
HvKd1pO70B84vD5OSrS7uNw2EYkjd/ZwhrJMrcQKRwPkkM4OiewaaAaK0vPWJIKw
lW61DY9X7LfNz7aOKMTbKnm1vdR0919AV98FUmNoQBgka6nXFGmNbi7D43MtLwxB
ZIXfFupEiANSvOs+57hgaCho7OWMGUOjLkG6HBscPhJ2W1H5DU9GjwL24ynTvKif
go1/2ue61MV1Pzh5CVaicJKNaRtgPd99gFhBGINsXV2X6Jh/W5nNsCddU4EI0AlO
8wIDAQAB
-----END PUBLIC KEY-----

Comme vous pouvez le voir, les clés de chiffrement asymétriques sont de longues séquences de caractères générées mathématiquement.

Nous avons donc généré les clés. Écrivons maintenant une fonction pour encoder les données:

 from Crypto.PublicKey import RSA #        RSA. from Crypto.Hash import SHA256 #        SHA256.    #       from Crypto.Cipher import PKCS1_OAEP #   def encrypt_message(message, public_key, verbose = True): """Encripts the message using public_key. :param message: <str> Message for encryption :param public_key: <object> public_key :param verbose: <bool> Print description; :return: <object> Message encrypted with public_key """ message_hash = SHA256.new(message.encode()) #   . cipher = PKCS1_OAEP.new(public_key) message_with_hash = message.encode() + message_hash.hexdigest().encode() #      ,          encrypted_message = cipher.encrypt(message_with_hash) if verbose: print(f'Message: {message} was encrypted to\n{encrypted_message.hex()}') return encrypted_message def decrypt_message(encrypted_message, private_key): """Decripts the message using private_key and check it's hash :param encrypted_message: <object> Encrypted message :param private_key: <object> private_key :return: <object> Message decripted with private_key """ dsize = SHA256.digest_size*2 cipher = PKCS1_OAEP.new(private_key) decrypted_message_with_hesh = cipher.decrypt(encrypted_message) #   (  ) decrypted_message = decrypted_message_with_hesh[:-dsize] #      digest = SHA256.new(decrypted_message).hexdigest() #     if digest==decrypted_message_with_hesh[-dsize:].decode(): #      ,      ,   print(f"Success!\nEncrypted hash is {decrypted_message_with_hesh[-dsize:].decode()}\nDecrypted hash is {digest}") return decrypted_message.decode() else: print(f"Encryption was not correct: the hash of decripted message doesn't match with encrypted hash\nEncrypted hash is {decrypted_message_with_hesh[-dsize:]}\nDecrypted hash is {digest}") 

Étapes du workflow
  1. L'agent génère une paire de clés:
     private_key, public_key = generate_keys() 

  2. Envoie la clé OUVERTE au siège;
  3. Au siège, à l'aide de la clé publique, encodez la clé pour le chiffrement symétrique:
     new_symmetric_key = 'SOME_KEY_asdfasdfasdfasdfsdfgrtwhetynt' encr_msg = encrypt_message(new_symmetric_key, public_key) 

    Conclusion
    Message: SOME_KEY_asdfasdfasdfasdfsdfgrtwhetynt was encrypted to
    41e940507c96397e3feb4a53390c982633bb1775a52957996a8069bd22063086a0e831bf775a17909276aba0d0478ee6c953837c8ea5d20d40e1c8eb463aaa1bc5c93c71677b1a85e90439c9dbda8a98ce168acb38368155437c66815b84aa2fbdda0eb909e4e6079b4410c720eddd955ed048193bf87f8f9976a17ee32a58a71dfddf3db116343d949d29c25f72c511a440a50a5d4f1e01c37b24a1cb4127e191d3231328b2f120c7dbd0cb5bf19823f0978b8ed17d25952de4b146ef9724fff359eb2af503fdfd72b91525a5503b076ba9aaaeac55af3f8d210c12d579d45dd70362123c0b4b36ef9c2f7705e6f884a25553eb0e11e5077f11fa986d0ff280


  4. Cette longue séquence est renvoyée à l'agent;
  5. L'agent déchiffre le message reçu à l'aide de la clé privée:
     recieved_symmetric_key = decrypt_message(encr_msg, private_key) print('\n') print(f"New symmetric key is: {recieved_symmetric_key}") 

    Conclusion
     Success! Encrypted hash is 42ad66445a05ac09e684bb21f9b487d95b9cfa11d02e0b459931321ee02f7c1c Decrypted hash is 42ad66445a05ac09e684bb21f9b487d95b9cfa11d02e0b459931321ee02f7c1c New symmetric key is: SOME_KEY_asdfasdfasdfasdfsdfgrtwhetynt 


  6. Ensuite, à l'aide d'une nouvelle clé symétrique, l'agent crypte les données reçues:

     message = """  120   120  / 120   10     30-5 (2)    4.0 """ encr_message = symmetric_encrypt(message, recieved_symmetric_key, verbose = True) 

    Conclusion
     Message was encrypted into: 


  7. Le siège décrypte:
     print('DECRIPTION') decr_message = symmetric_decrypt(encr_message, new_symmetric_key) print(decr_message) 

    Conclusion
     DECRIPTION Success! Encrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026 Decrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026  120   120  / 120   10     30-5 (2)    4.0 




Voila!

Dans cet exemple abstrait, nous avons vu le travail d'algorithmes de chiffrement courants. Le chiffrement symétrique et asymétrique, ainsi que le hachage, sont utilisés dans le travail sur le Web , la signature électronique , la blockchain et les crypto-monnaies . J'espère que le matériel a été utile pour comprendre le fonctionnement de ces technologies.

Postface


En conséquence, les renseignements rebelles ont réussi à obtenir des informations précises sur la vulnérabilité de la station et son cheminement, la présence de l'empereur pour inspection, la présence d'un bouclier énergétique et sa source sur Endor. L'empire a repéré les espions, les a mal informés sur la capacité de combat de la station. La station a également été attribuée au satellite d'Endor, d'où il était protégé par un bouclier.

Mais nous savons comment tout cela s'est terminé;)

Source: https://habr.com/ru/post/fr452042/


All Articles