Algorithme de chiffrement RSA
Passons en revue l'algorithme de cryptage de RSA. Nous utilisons un langage relativement standardisé pour décrire cet algorithme en fonction de la définition de l'algorithme de cryptage de clé publique et de l'algorithme de signature.
Le système de chiffrement de clé publique RSA comprend les 3 algorithmes suivants: keygen (algorithme de génération de clés), ECRYPT (ECRYPT) et Decrypt (algorithme de décryptage).
L'algorithme de génération de clés utilise une constante de sécurité comme entrée pour sortir une clé publique PK et une clé privée SK. La constante de sécurité est utilisée pour déterminer la sécurité de l'algorithme de cryptage, qui est généralement lié à la taille du numéro Prime P utilisé par l'algorithme de chiffrement. Plus le nombre privil est grand, plus le système est grand, garantissant une sécurité plus élevée. Dans RSA, l'algorithme de génération de clés est le suivant: l'algorithme génère d'abord deux grands nombres premiers différents P et Q différents, et calcule n = pq. Ensuite, l'algorithme calcule la fonction Euler. Ensuite, l'algorithme sélectionne au hasard un entier inférieur à E et calcule l'élément inverse du modulo d de e. Enfin, la clé publique est pk = (n, e) et la clé privée est sk = (n, d).
L'algorithme de cryptage utilise la clé publique PK et le message m à crypter en entrée et publie le CT de texte chiffré. Dans RSA, l'algorithme de chiffrement est le suivant: l'algorithme publie directement le texte chiffré car l'algorithme de décryptage utilise la clé privée SK et le CT de texte chiffré comme entrées, et publie le message M. Dans le texte RSA, l'algorithme de décryptage est directement. Puisque E et D sont inversement opposés les uns aux autres, nous avons:
Par conséquent, à partir de la description de l'algorithme, nous pouvons également voir que la clé publique est utilisée pour crypter les données, et la clé privée est utilisée pour décrypter les données. Bien sûr, cela peut également être compris intuitivement: une clé publique est une clé publique, et ce n'est que lorsqu'elle est divulguée que tout le monde peut l'utiliser pour crypter les données. Une clé privée est une clé privée, et quiconque a cette clé peut décrypter le texte chiffré. Sinon, si tout le monde peut voir la clé privée et le décrypter, ce sera un gâchis.
Jetons un coup d'œil à l'implémentation simple en Java:
Package Com.stone.Security; Importer java.security.KeyPair; Importer java.security.KeyPairGenerator; import java.security.privatekey; Importer java.security.publickey; import java.util.arrays; import javax.crypto.cipher; / ** * RSA Algorithm Clé public Encryption Asymmetric Encryption * / public class rsa {public static final String key_algorithm = "rsa"; Public Static Final String cipher_algorithm_ecb1 = "RSA / ECB / PKCS1PADDING"; String final statique publique cipher_algorithm_ecb2 = "RSA / ECB / OAEPWITHSHA-1Andmgf1padding"; // Vous ne pouvez pas utiliser la chaîne finale statique publique cipher_algorithm_ecb3 = "oaepwithsha-256andmgf1padding"; // Vous ne pouvez pas utiliser Static PublicKey PublicKey; STATIQUE PRIVATEKEY PRIVATEKEY; Cipher statique; clés statique de la clés; public static void main (String [] args) lève une exception {méthode1 ("skoda u * (sfsad7f () * ^ %% $"); méthode2 ("skoda u * (sfsad7f () * ^ %% $"); Method3 ("Skoda u * (Sfsad7f () * ^ %% $");} / ** * CiPher_algorithm_ecb1 * @param str * @throws exception * / static void method1 (string str) lève exception {keyPairGenerator KeyGenerator = keyPairGenerator.getInSitance (key_algorithm); KeyPair.getPrivate (); Arrays.tostring (Encrypt)); Cipher_algorithm_ecb1 * @param str * @throws exception * / static void method2 (string str) lève exception {keyPairGenerator keyGenerator = keyPairGenerator.getInstance (key_algorithm); Keypair keypAir = keyGenerator.generateKeyPair (); publicKey = keyPair.getPublic (); privateKey = keyPair.getPrivate (); cipher = cipher.getInstance (key_algorithm); cipher.init (cipher.encrypt_mode, privateKey); // Entrée de cryptage de clé privée [] Encrypt = cipher.dofinal (str.getBytes ()); System.out.println ("Encryption de clé privée 2:" + arrays.toString (Encrypt)); cipher.init (cipher.decrypt_mode, publicKey); // Decrypt de la clé publique BYTE [] Decrypt = Cipher.Dofinal (Encrypt); System.out.println ("Public Key Decrypt 2:" + New String (Decrypt)); } / ** * Encryption de clé privée, le décryptage de la clé publique utilise CIPHER_ALGORITHM_ECB1 = RSA / ECB / PKCS1PADDING * @param str * @throws exception * / static void Method3 (String Str) exception {keypairgenerator keyGenerator = keyPairgenerator.getInstance (key_algorithm); Keypair keypAir = keyGenerator.generateKeyPair (); publicKey = keyPair.getPublic (); privateKey = keyPair.getPrivate (); cipher = cipher.getInstance (cipher_algorithm_ecb1); cipher.init (cipher.encrypt_mode, privateKey); // Entrée de cryptage de clé privée [] Encrypt = cipher.dofinal (str.getBytes ()); System.out.println ("Encryption de clé privée 3:" + arrays.tostring (Ecrypt)); cipher.init (cipher.decrypt_mode, publicKey); // byte de décryptage de clé publique [] Decrypt = cipher.dofinal (crypt); System.out.println ("3 après le décryptage des clés publics:" + Nouvelle chaîne (décrypt)); }} Algorithme DSA et signature numérique
La DSA est généralement utilisée pour les signatures numériques et la certification.
La DSA est une variante des algorithmes de signature Schnorr et Elgamal, et est utilisé par le NIST aux États-Unis en tant que DSS (Norme de signature numérique).
La DSA est basée sur le problème logarithmique discret du domaine fini entier, et sa sécurité est similaire à RSA.
Dans la signature et l'authentification numériques de DSA, l'expéditeur utilise sa propre clé privée pour signer un fichier ou un message, et le destinataire utilise la clé publique de l'expéditeur pour vérifier l'authenticité de la signature après avoir reçu le message. La DSA n'est qu'un algorithme, et la différence entre RSA est qu'elle ne peut pas être utilisée pour le cryptage et le décryptage, ni pour l'échange de clés.
Pour les signatures seulement, il est beaucoup plus rapide que RSA.
Package Com.stone.Security; Importer java.security.key; import java.security.keyfactory; Importer java.security.KeyPair; Importer java.security.KeyPairGenerator; import java.security.privatekey; Importer java.security.publickey; Importer Java.Security.SeCurère et; importation java.security.signature; Importer java.security.spe.pkcs8encodedKeyspec; Importer java.security.spec.x509encodedKeyspec; import java.util.hashmap; importation java.util.map; IMPORT SUN.MISC.BASE64DECODER; Import Sun.Misc.Base64Encoder; / ** * L'algorithme de signature-numérique DSA est une variante des algorithmes de signature Schnorr et Elgamal, et est utilisé comme DSS par NIST aux États-Unis. * En bref, il s'agit d'une méthode de vérification plus avancée utilisée comme signature numérique. Non seulement les clés publiques et privées, mais aussi les signatures numériques. Le cryptage des clés privés génère des signatures numériques, des données de vérification des clés publiques et des signatures. * Si les données et la signature ne correspondent pas, la vérification sera considérée comme étant l'échec! C'est-à-dire que les données de transmission ne peuvent plus être cryptées. Une fois que le récepteur a obtenu les données, il obtient la clé publique et la signature pour vérifier si les données sont valides. * / classe publique DSA {/ ** * Non seulement vous pouvez utiliser l'algorithme DSA, mais vous pouvez également utiliser l'algorithme RSA pour les signatures numériques * / la chaîne finale statique publique key_algorithme = "RSA"; public static final String signature_algorithm = "md5withrsa"; * / public static final string key_algorithm = "dsa"; public static final String signature_algorithm = "dsa"; public static final String default_seed = "$% ^ *% ^ () (hjg8awfjas7"; // par défaut semence publique statique final chaîne public_key = "dsapublickey"; public static final string private_key = "dsaprivatekey Vous * () _ + "; byte [] data = str.getBytes (); map <string, object> keymap = initkey (); // construire clés public publicyey = (publickey) keymap.get (public_key); privateKeykeyy = (privateKey) keymap.get (private_key); System.out.println (" private key format: "+ privatekey.getFormat (); System.out.println ("Format de clé publique:" + publicKey.getFormat ()); Verify1); Boolean Verify = Verify (data, getPublicKey (keymap), signe); } / ** * générer une clé * * @param semence de graine * @return Key Object * @throws exception * / public static map <String, object> initkey (String Seed) lève l'exception {System.out.println ("Generate Key"); KeyPairGenerator keygen = keyPairGenerator.getInstance (key_algorithm); SecureRandom SecureRandom = new SecureRandom (); SecureRandom.SetEed (Seed.getBytes ()); // La taille du module doit varier de 512 à 1024 et être un multiple de 64 keygen.Initialize (640, SecureRandom); Keypair keys = keygen.genkeypair (); PrivateKey privateKey = keys.getPrivate (); PublicKey publicKey = keys.getPublic (); Map <string, objet> map = new hashmap <string, objet> (2); map.put (public_key, publicKey); map.put (private_key, privateKey); carte de retour; } / ** * Générer la clé par défaut * * @return Key Object * @throws Exception * / public static map <string, object> initkey () lève exception {return initKey (default_seed); } / ** * Obtenez la clé privée * * @param keymap * @return * @throws exception * / public static String getPrivateKey (map <string, object> keymap) lève exception {key key = (key) keymap.get (private_key); return EncryptBase64 (key.getEncoded ()); // Base64 Encryption Private Key} / ** * Obtenez la clé publique * * @param keymap * @return * @throws exception * / public static String getPublicKey (map <string, object> keymap) lève exception {key key = (key) keymap.get (public_key); return EncryptBase64 (key.getEncoded ()); // Base64 Encryption Clé publique} / ** * Utilisez la clé privée pour signer numériquement les informations * @param données données chiffrées * @param privateKey Key - Base64 Encrypted * @return * @throws exception * / public static Signal ("Digitize Data, String PrivateKey) lance l'exception {System.out.println (" Digitize les informations avec la clé privée "); octet [] keyBytes = decryptBase64 (privateKey); Pkcs8EncodedKeyspec keySpec = new PKCS8EncodedKeyspec (keyBytes); KeyFactory factory = keyfactory.getInstance (key_algorithm); PrivateKey prikey = factory.generatePrivate (keyspec); // générer des informations privées // normessign avec une clé privée signature = signature.getInstance (signature_algorithm); Signature.InitSign (prikey); Signature.Update (données); return EncryptBase64 (signature.sign ()); } / ** * Base64Encoder Encryption * @Param Données Données à crypter * @return ENCRYPTED String * / private static String EncryptBase64 (byte [] data) {Base64Encoder Encoder = new Base64Encoder (); Chaîne encode = Encoder.encode (données); retour encode; } / ** * Base64Decoder Decrypt * @param String de données à décrypter * @return décrypté octet [] * @throws exception * / private static byte [] decryptBase64 (String data) lève exception {base64decoder decoder = new Base64DecOder (); octet [] buffer = decoder.decodeBuffer (données); tampon de retour; } / ** * Vérifier la signature numérique * @param Données Données chiffrées * @param publickey * @param signe Signature numérique * @return * @throws exception * / public static boolean Verify (byte [] data, string publicKey (String Sign) exception {byte [] keybytes = decryptBase64 (publicKey); X509EncodedKeyspec KeySpec = new x509encodedKeyspec (keyBytes); KeyFactory keyFactory = keyFactory.getInstance (key_algorithm); Publicy pubkey = keyfactory.generatePublic (keySpec); Signature signature = signature.getInstance (signature_algorithm); Signature.Initverify (pubkey); Signature.Update (données); return Signature.Verify (deCryptBase64 (signe)); // Vérifiez la signature}}