Concept de mot de passe asymétrique
1. La principale différence par rapport aux algorithmes de cryptage symétrique est que les clés de cryptage et de décryptage sont différentes, l'une est publique (clé publique) et l'autre est confidentielle (clé privée). Il résout principalement le problème de la gestion de l'allocation clé des algorithmes de chiffrement symétrique et améliore la sécurité des algorithmes.
2. L'efficacité de cryptage et de décryptage des algorithmes de cryptage asymétrique est relativement faible. Dans la conception de l'algorithme, les algorithmes de chiffrement asymétriques ont des exigences strictes sur la durée des données cryptées. Par exemple, l'algorithme RSA exige que les données soient cryptées ne doivent pas être supérieures à 53 octets.
3. Les algorithmes de chiffrement asymétriques sont principalement utilisés pour échanger des clés des algorithmes de chiffrement symétriques, plutôt que l'échange de données.
4. Java6 fournit deux algorithmes qui implémentent DH et RSA. Bouncy Castle fournit un support d'algorithme E1Gamal. En plus des trois algorithmes ci-dessus, il existe également un algorithme ECC, et il n'y a actuellement aucun composant open source pertinent pour fournir un support.
Deux clés sont nécessaires pour le cryptage ou le décryptage, divisé en clés publiques et privées
Caractéristiques: Sécurité élevée, vitesse lente
utiliser
【Échange de clés (DH)】
Sans déterminer la clé commune, les deux parties génèrent la clé et ne fournissent pas de travail de chiffrement. Le chiffrement et le décryptage nécessitent également d'autres algorithmes de cryptage symétriques pour implémenter.
Exemple d'algorithme DH
Importer javax.crypto.keyagrement; import javax.crypto.interfaces.dhprivateKey; import javax.crypto.interfaces.dhpublickey; import javax.crypto.spec.dhparameterspec; import java.security. java.security.spec.x509encodedKeyspec; import java.util.hashmap; import java.util.map; // 1 générer la clé de la source // 2 La clé publique de la source est remise à la cible, et la cible génère la clé publique et la clé privée par le biais de la source. // 3 La clé publique de la cible est remise à la source // 4 Les deux parties utilisent la clé publique de l'autre partie et sa propre clé privée pour générer la clé locale // 5 Si les deux parties génèrent la clé locale de la même manière, complétez la classe publique d'échange de clé Dhutil {public static final String public_key = "DH_PUBLIC_KEY"; public static final String private_key = "dh_private_key"; / ** * Générer la paire de clés source * @return * @throws exception * / public static map <string, object> initsourcekey () lève exception {// créer une instance de keyPairGenerator, sélectionnez l'algorithme dh keypairgenerator keypArGenerator = keyPairgenerator.getInstance ("dh"); // Initialisez la longueur de la clé, par défaut 1024, plage facultative 512-65536 et multiples de 64 KeyPairGenerator.Initialize (1024); // Générer Key Pair KeyPair KeyPAir = KeyPairGenerator.GenerateKeyPair (); Dhpublickey dhpublickey = (dhpublickey) keypair.getPublic (); DhPrivateKey dhPrivateKey = (dhPrivateKey) keypair.getPrivate (); // Mettez la paire de clés dans la carte map <string, objet> keymap = new hashmap <string, objet> (); keymap.put (public_key, dhpublickey); keymap.put (private_key, dhPrivateKey); retour keymap; } / ** * Générez la paire de clés cibles via la touche publique source * @param sourcePublicKey * @return * @throws exception * / public static map <string, object> inittargetKey (byte [] sourcePublicKey) lève exception {keyfactory keyfactory = keyfactory.getInstance ("dh"); // Utilisez la touche publique source, générez KeySpec et utilisez KeyFactory pour générer des informations liées à Source PublicKey x509EncodedKeyspec KeySpec = new x509EncodedKeyspec (sourcePublicKey); Dhpublickey sourcepublic = (dhpublickey) keyfactory.generatePublic (keySpec); DhParameterspec dhpublickeyParams = sourcePublic.getParams (); KeyPAirGenerator KeyPAirGenerator = KeyPairGenerator.getInstance ("DH"); KeyPairGenerator.Initialize (dhpublickeyparams); Keypair keypair = keypairgenerator.generateKeypair (); Dhpublickey dhpublickey = (dhpublickey) keypair.getPublic (); DhPrivateKey dhPrivateKey = (dhPrivateKey) keypair.getPrivate (); // Mettez la paire de clés dans la carte map <string, objet> keymap = new hashmap <string, objet> (); keymap.put (public_key, dhpublickey); keymap.put (private_key, dhPrivateKey); retour keymap; } / ** * Utilisez la clé publique d'une partie et la clé privée de l'autre partie pour générer la clé locale * @return * / public static byte [] generatelocalcretkey (byte [] apublickey, byte [] bprivateKey) lance l'exception {keyfactory keyfactory = keyfactory.getInstance ("dh"); // Utilisez une clé publique, générez KeySpec et utilisez KeyFactory pour générer une information liée à PublicKey x509EncodedKeyspec KeySpec = new x509EncodedKeyspec (apublicKey); PublicKey publicKey = keyfactory.generatePublic (keySpec); // Utiliser B Clé privée, générer B PrivateKey Informations liées PKCS8EncodedKeyspec PKCS8EncodedKeyspec = new PKCS8EncodedKeyspec (BPrivateKey); PrivateKey privateKey = keyfactory.generatePrivate (pkcs8encodedKeyspec); // Encrypt A de PublicKey de A et B PrivateKey de B via KeyAgrement Keyagrement keyagrement = keyagrement.getInstance ("dh"); keyagrement.init (privateKey); keyagrement.dophase (publickey, true); return keyagrement.GenerateSecret ("aes"). getEncoded (); // L'algorithme utilise un algorithme de chiffrement symétrique (Des, Deede, aes) // return keyagrement.generateSeret (); // L'algorithme peut également être utilisé pour calculer en utilisant la méthode par défaut sans sélectionner l'algorithme} // Obtenez le tableau de clés public-byte public static byte [] getPublicKey (map <string, object> map) {return ((dhpublicKey) map.get (public_key)). GetEncoded (); } // Obtenez le tableau d'octet de clé privé Public Static octet [] getPrivateKey (map <string, object> map) {return ((dhprivatekey) map.get (private_key)). GetEncoded (); } public static void main (String [] args) lève une exception {byte [] source_public_key; octet [] source_private_key; octet [] source_local_key; octet [] cible_public_key; octet [] cible_private_key; octet [] cible_local_key; Map <string, object> sourceKey = initsourceKey (); source_public_key = getPublicKey (sourceKey); source_private_key = getPrivateKey (sourceKey); System.out.println ("Source Public Key:" + ByTestoHEx.FrombyTestOhex (source_public_key)); System.out.println ("Source Private Key:" + ByTestoHEx.FrombyTestOhex (source_private_key)); Map <string, object> targetKey = inittargetKey (getPublicKey (sourceKey)); Target_public_key = getPublicKey (TargetKey); Target_private_key = getPrivateKey (TargetKey); System.out.println ("Target Public Key:" + ByTestoHEx.FrombyTestOhex (Target_Public_Key)); System.out.println ("Target Private Key:" + ByTestoHEx.FrombyTestOhex (Target_private_Key)); source_local_key = GenerateloCalSecretKey (cible_public_key, source_private_key); Target_Local_Key = GenerateLocalSecretKey (source_public_key, cible_private_key); System.out.println ("Source Key local:" + byTestoHEx.FrombyTestOhex (source_local_key)); System.out.println ("Target Key local:" + byTestoHEx.FrombyTestoHEX (Target_Local_Key)); }}【Encryption / décryptage (RSA) 】【 Signature numérique (RSA)】
L'algorithme RSA est plus tard que l'algorithme DH, et toutes ces cinq lettres sont les premières lettres du nom humain. L'algorithme DH est le premier système cryptographique asymétrique.
L'algorithme RSA a une vitesse de calcul lente et ne convient pas pour chiffrer de grandes quantités de données. Une solution consiste à mélanger les méthodes de chiffrement RSA et symétriques, les données de crypte à l'aide de méthodes de chiffrement symétriques et les clés de chiffrement symétriques sont cryptées à l'aide d'algorithmes RSA. Parce que la clé est très courte, le temps n'est pas trop. En fait, le seul inconvénient des méthodes de cryptage symétrique est que la clé est difficile à passer et que les méthodes de cryptage symétriques sont également difficiles à casser.
Scénarios applicables de RSA:
(1) Le serveur génère une clé publique et une clé privée et publie la clé publique.
(2) Le client utilise une clé publique pour crypter les données et la remettre au serveur. D'autres ne peuvent pas comprendre les données cryptées.
(3) Le serveur utilise une clé privée pour décrypter les données et afficher les données soumises par l'utilisateur.
Dans ce cas, la clé publique est comme une boîte aux lettres, et tout le monde peut mettre un message dans cette boîte aux lettres, mais seuls ceux qui ont les clés de boîte aux lettres peuvent déballer et afficher les lettres de cette boîte aux lettres.
Scénario applicable RSA 2:
(1) L'empereur génère une clé publique et une clé secrète et publie la clé publique.
(2) L'empereur a publié un édit pour informer le monde. Il y a deux chaînes de nombres dans le coin inférieur droit de l'édit. La première chaîne est une chaîne aléatoire, et la deuxième chaîne est le résultat de la cryptage de la première chaîne avec une clé privée.
(3) Certaines personnes ne croient pas que l'édit a été écrit par l'empereur, ils ont donc déchiffré la deuxième série de nombres en utilisant la clé publique. Après avoir décrypté, ils ont constaté que c'était la même chose que la première série de nombres, ce qui signifie qu'il a en effet été écrit par l'empereur. Parce que la plupart des gens n'ont pas de clé, ils ne peuvent pas crypter les données qui peuvent être déchiffrées avec la clé publique.
Dans ce cas, la clé publique est utilisée pour le déchiffrement et la clé privée est utilisée pour le cryptage. Cela peut être utilisé pour prouver que l'annonce a en effet été envoyée par quelqu'un. Il équivaut à une signature.
En fait, il n'est pas nécessaire d'être particulièrement long pour les signatures. D'une manière générale, les signatures sont de longueur fixe. Si vous souhaitez avoir une longueur fixe, vous pouvez utiliser l'algorithme MessagediGest, tel que MD5 et SHA. Par conséquent, il existe une variété d'algorithmes de signature, tels que MD5 Withrsa, etc.
Exemples de cryptage / décryptage RSA
Importer javax.crypto.cipher; import java.security.keypair; import java.security.keypairgenerator; import java.security.publickey; import java.security.interfaces.rsaprivatekey; import java.security.interfaces.rsapublickey; import import java.util.hashmap; java.util.map; / ** * Tool de chiffrement RSA * / classe publique rsautil {public static final String public_key = "rsa_public_key"; public static final String private_key = "rsa_private_key"; / ** * Key d'initialisation * @return * @throws exception * / public static map <String, object> initKey () lève exception {keyPairGenerator keypArGenerator = keyPairGenerator.getInstance ("rsa"); KeyPairGenerator.Initialize (1024); // 512-65536 & Multiples de 64 keypair keypair = keypairgenerator.generateKeyPair (); RSAPublicKey PublicKey = (RSAPublickey) KeyPair.getPublic (); RsaprivateKey privateKey = (rsaprivateKey) keypair.getPrivate (); Map <string, object> keymap = new HashMap <String, Object> (); keymap.put (public_key, publicKey); keymap.put (private_key, privateKey); retour keymap; } public static rsapublickey getPublicKey (map <string, objet> keymap) {return (rsapublickey) keymap.get (public_key); } public static rsaprivateKey getPrivateKey (map <string, objet> keymap) {return (rsaprivateKey) keymap.get (private_key); } / ** * Crypt Données à l'aide de la clé publique * @param Données * @param publicKey * @return * @throws exception * / public static octet [] Encrypt (byte [] data, rsapublickey publickey) lève exception {cipher cipher = cipher.getInstance ("rsa"); Cipher.init (cipher.encrypt_mode, publicKey); return cipher.dofinal (données); } / ** * Utilisez la clé privée pour décrypter * @param data * @param privateKey * @return * @throws exception * / public static octet [] decrypt (byte [] data, rsaprivatekey privateKey) lève exception {cipher cipher = cipher.getInstance ("rsa"); cipher.init (cipher.decrypt_mode, privateKey); return cipher.dofinal (données); } public static void main (String [] args) lève une exception {String data = "jay chou-dongfeng Break"; Map <string, object> keymap = initkey (); octet [] miwen = Encrypt (data.getBytes (), getPublicKey (keymap)); System.out.println ("Contenu chiffré:" + byTestOhex.FrombyTestOhex (Miwen)); octet [] Plain = Decrypt (miwen, getPrivateKey (keymap)); System.out.println ("Contenu décrypté:" + New String (PLAIN)); }}Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.