Asymmetric password concept
1. The main difference from symmetric encryption algorithms is that the encryption and decryption keys are different, one is public (public key) and the other is confidential (private key). It mainly solves the problem of key allocation management of symmetric encryption algorithms and improves algorithm security.
2. The encryption and decryption efficiency of asymmetric encryption algorithms is relatively low. In algorithm design, asymmetric encryption algorithms have strict requirements on the length of encrypted data. For example, the RSA algorithm requires that the data to be encrypted must not be greater than 53 bytes.
3. Asymmetric encryption algorithms are mainly used to exchange keys of symmetric encryption algorithms, rather than data exchange.
4. Java6 provides two algorithms that implement DH and RSA. Bouncy Castle provides E1Gamal algorithm support. In addition to the above three algorithms, there is also an ECC algorithm, and there is currently no relevant open source component to provide support.
Two keys are required for encryption or decryption, divided into public and private keys
Features: High safety, slow speed
use
【Key Exchange (DH)】
Without determining the common key, both parties generate the key and do not provide encryption work. Encryption and decryption also requires other symmetric encryption algorithms to implement.
DH algorithm example
import javax.crypto.KeyAgreement;import javax.crypto.interfaces.DHPrivateKey;import javax.crypto.interfaces.DHPublicKey;import javax.crypto.spec.DHParameterSpec;import java.security.*;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;//1 Generate source key//2 The public key of the source is handed over to the target, and the target generates the public key and private key through the source. //3 The public key of the target is handed over to the source//4 Both parties use the other party's public key and its own private key to generate the local key//5 If both parties generate the local key the same, complete the key exchange public class DHUtil { public static final String PUBLIC_KEY = "DH_Public_Key"; public static final String PRIVATE_KEY = "DH_Private_key"; /** * Generate source key pair* @return * @throws Exception */ public static Map<String,Object> initSourceKey() throws Exception{ //Create an instance of KeyPairGenerator, select the DH algorithm KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH"); //Initialize the key length, default 1024, optional range 512-65536 & multiples of 64 keyPairGenerator.initialize(1024); //Generate key pair KeyPair keyPair = keyPairGenerator.generateKeyPair(); DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic(); DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate(); //Put the key pair into Map Map<String,Object> keyMap = new HashMap<String, Object>(); keyMap.put(PUBLIC_KEY, dhPublicKey); keyMap.put(PRIVATE_KEY, dhPrivateKey); return keyMap; } /** * Generate the target key pair through the source public key* @param sourcePublicKey * @return * @throws Exception */ public static Map<String,Object> initTargetKey(byte[] sourcePublicKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("DH"); //Use the source public key, generate keySpec, and use KeyFactory to generate source PublicKey related information 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(); //Put the key pair into Map Map<String,Object> keyMap = new HashMap<String, Object>(); keyMap.put(PUBLIC_KEY, dhPublicKey); keyMap.put(PRIVATE_KEY, dhPrivateKey); return keyMap; } /** * Use one party's public key and the other party's private key to generate the local key* @return */ public static byte[] generateLocalSecretKey(byte[] aPublicKey, byte[] bPrivateKey) throws Exception{ KeyFactory keyFactory = KeyFactory.getInstance("DH"); //Use A public key, generate keySpec, and use KeyFactory to generate A PublicKey related information X509EncodedKeySpec keySpec = new X509EncodedKeySpec(aPublicKey); PublicKey publicKey = keyFactory.generatePublic(keySpec); //Use B private key, generate B PrivateKey related information PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bPrivateKey); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // Encrypt A's PublicKey and B's PrivateKey through KeyAgreement KeyAgreement keyAgreement = KeyAgreement.getInstance("DH"); keyAgreement.init(privateKey); keyAgreement.doPhase(publicKey,true); return keyAgreement.generateSecret("AES").getEncoded();//The algorithm uses symmetric encryption algorithm (DES, DESede, AES) //Return keyAgreement.generateSecret(); //The algorithm can also be used to calculate using the default method without selecting the algorithm} //Get the public key byte array public static byte[] getPublicKey(Map<String,Object> map){ return ((DHPublicKey) map.get(PUBLIC_KEY)).getEncoded(); } //Get the private key byte array public static byte[] getPrivateKey(Map<String,Object> map){ return ((DHPrivateKey) map.get(PRIVATE_KEY)).getEncoded(); } public static void main(String[] args) throws Exception { byte[] source_public_key; byte[] source_private_key; byte[] source_local_key; byte[] target_public_key; byte[] target_private_key; byte[] target_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(target_public_key, source_private_key); target_local_key = generateLocalSecretKey(source_public_key, target_private_key); System.out.println("Source local key: "+BytesToHex.fromBytesToHex(source_local_key)); System.out.println("Target local key: "+BytesToHex.fromBytesToHex(target_local_key)); }}【Encryption/Decryption (RSA)】【Digital Signature (RSA)】
The RSA algorithm is later than the DH algorithm, and all of these five letters are the first letters of the human name. The DH algorithm is the first asymmetric cryptographic system.
The RSA algorithm has a slow computing speed and is not suitable for encrypting large amounts of data. One solution is to mix RSA and symmetric encryption methods, encrypt data using symmetric encryption methods, and symmetric encryption keys are encrypted using RSA algorithms. Because the key is very short, the time is not too much. In fact, the only disadvantage of symmetric encryption methods is that the key is difficult to pass, and symmetric encryption methods are also difficult to crack.
Applicable scenarios of RSA:
(1) The server generates a public key and a private key, and publicizes the public key.
(2) The client uses a public key to encrypt the data and hand it over to the server. Others cannot understand the encrypted data.
(3) The server uses a private key to decrypt the data and view the data submitted by the user.
In this case, the public key is like a mailbox, and everyone can put a message into this mailbox, but only those who have the mailbox keys can unbox and view the letters in this mailbox.
RSA applicable scenario 2:
(1) The emperor generates a public key and a secret key, and publicizes the public key.
(2) The emperor issued an edict to inform the world. There are two strings of numbers in the lower right corner of the edict. The first string is a random string, and the second string is the result of encrypting the first string with a private key.
(3) Some people do not believe that the edict was written by the emperor, so they decrypted the second string of numbers using the public key. After decrypting, they found that it was the same as the first string of numbers, which means that it was indeed written by the emperor. Because most people do not have a key, they cannot encrypt the data that can be decrypted with the public key.
In this case, the public key is used for decryption and the private key is used for encryption. This can be used to prove that the announcement was indeed sent by someone. It is equivalent to a signature.
In fact, there is no need to be particularly long for signatures. Generally speaking, signatures are fixed-length. If you want to have fixed-length, you can use the MessageDigest algorithm, such as MD5 and SHA series. Therefore, there are a variety of signature algorithms, such as MD5 withRSA, etc.
RSA encryption/decryption examples
import 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 java.util.HashMap;import java.util.Map;/** * RSA encryption tool*/public class RSAUtil { public static final String PUBLIC_KEY = "RSA_Public_Key"; public static final String PRIVATE_KEY = "RSA_Private_Key"; /** * Initialization key* @return * @throws Exception */ public static Map<String,Object> initKey() throws Exception{ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024);//512-65536 & multiples of 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); return keyMap; } public static RSAPublicKey getPublicKey(Map<String,Object> keyMap) { return (RSAPublicKey) keyMap.get(PUBLIC_KEY); } public static RSAPrivateKey getPrivateKey(Map<String,Object> keyMap){ return (RSAPrivateKey) keyMap.get(PRIVATE_KEY); } /** * Encrypt data using public key* @param data * @param publicKey * @return * @throws Exception */ public static byte[] encrypt(byte[] data, RSAPublicKey publicKey) throws Exception{ Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE,publicKey); return cipher.doFinal(data); } /** * Use the private key to decrypt* @param data * @param privateKey * @return * @throws Exception */ public static byte[] decrypt(byte[] data, RSAPrivateKey privateKey) throws Exception{ Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE,privateKey); return cipher.doFinal(data); } public static void main(String[] args) throws Exception { String data = "Jay Chou-Dongfeng Break"; Map<String, Object> keyMap = initKey(); byte[] miwen = encrypt(data.getBytes(),getPublicKey(keyMap)); System.out.println("Encrypted content: "+BytesToHex.fromBytesToHex(miwen)); byte[] plain = decrypt(miwen, getPrivateKey(keyMap)); System.out.println("Decrypted content: "+new String(plain)); }}The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.