English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

JAVA Encryption Algorithm- Detailed Introduction to Asymmetric Encryption Algorithms (DH, RSA)

Asymmetric Cryptography Concept

1、The main difference from symmetric encryption algorithms is that the encryption and decryption keys are different, one public (public key), one secret (private key). It mainly solves the problem of key distribution and management in symmetric encryption algorithms, and improves the security of the algorithm.

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 the data to be encrypted. For example, the RSA algorithm requires that the data to be encrypted must not exceed53bytes.

3、Asymmetric encryption algorithms are mainly used for exchanging the keys of symmetric encryption algorithms, rather than data exchange

4、java6Provide implementations of both DH and RSA algorithms. Bouncy Castle provides E1Gamal algorithm supported. In addition to the above three algorithms, there is also an ECC algorithm, and there are currently no open source components available to support it

Two keys are required for encryption or decryption, divided into public key and private key

Characteristics: High security, slow speed

Purpose

[Key Exchange (DH)]

Both parties generate keys without determining a common key, do not provide encryption work, and encryption and decryption still require other symmetric encryption algorithms to be implemented

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 the source key
//2 Hand over the source public key to the target, the target generates the target public key and private key through the source public key
//3 Hand over the target public key to the source
//4 Both parties use the other party's public key and their own private key to generate local keys
//5 If both parties generate the same local key, the key exchange is completed
public class DHUtil {
  public static final String PUBLIC_KEY = "DH_Public_Key";
  public static final String PRIVATE_KEY = "DH_Private_key";
  /**
   * Generate the source key pair
   * @return
   * @throws Exception
   */
  public static Map<String, Object> initSourceKey() throws Exception{
    //Create an instance of KeyPairGenerator, using the DH algorithm
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
    //Initialize the key length, default1024, optional range512-65536 & 64multiple of
    keyPairGenerator.initialize(1024);
    //Generate the key pair
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
    DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
    //Put the key pair into the 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");
    //By using the source public key, generate keySpec, and use KeyFactory to generate related information of the 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();
    //Put the key pair into the Map
    Map<String, Object> keyMap = new HashMap<String, Object>();
    keyMap.put(PUBLIC_KEY, dhPublicKey);
    keyMap.put(PRIVATE_KEY, dhPrivateKey);
    return keyMap;
  }
  /**
   * Generate the local secret key using the public key of one party and the private key of the other party
   * @return
   */
  public static byte[] generateLocalSecretKey(byte[] aPublicKey, byte[] bPrivateKey) throws Exception{
    KeyFactory keyFactory = KeyFactory.getInstance("DH");
    //Generate keySpec through A public key, and use KeyFactory to generate A PublicKey related information
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(aPublicKey);
    PublicKey publicKey = keyFactory.generatePublic(keySpec);
    //Generate B PrivateKey related information through B private key
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bPrivateKey);
    PrivateKey privateKey = keyFactory.generatePrivate(pkcs)8EncodedKeySpec);
    //通过KeyAgreement对A的PublicKey和B的PrivateKey进行加密
    KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
    keyAgreement.init(privateKey);
    keyAgreement.doPhase(publicKey,true);
    return keyAgreement.generateSecret("AES").getEncoded();//算法使用对称加密算法(DES,DESede,AES)
    //return keyAgreement.generateSecret();        // 也可以不选择算法,使用默认方法计算
  }
  //获取公钥字节数组
  public static byte[] getPublicKey(Map<String,Object> map){
    return ((DHPublicKey) map.get(PUBLIC_KEY)).getEncoded();
  }
  //获取私钥字节数组
  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("源公钥:")+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 was developed later than the DH algorithm, and these five letters are all initials of people's names. The DH algorithm is the first asymmetric cryptographic system.

The RSA algorithm is slow in operation and is not suitable for encrypting large amounts of data. One solution is to use RSA in combination with symmetric encryption methods, encrypting the data with symmetric encryption methods, and encrypting the symmetric encryption key with the RSA algorithm. Since the key is short, it does not take too much time. In fact, the only drawback of symmetric encryption methods is that it is difficult to pass the key, and it is also difficult to crack.

The applicable scenarios of RSA:

)1) The server generates a public key and a private key and makes the public key public.

)2) The client uses the public key to encrypt the data and submit it to the server. Others cannot understand the encrypted data.

)3) The server uses the private key to decrypt the data and view the data submitted by the user.

In this scenario, the public key is like a mailbox. Everyone can put letters in this mailbox, but only the person who has the key to the mailbox can open the box to view the letters inside.

RSA applicable scenario two:

)1) The emperor generated a public key and a private key and made the public key public.

)2) The emperor issued an edict, announcing to the world. At the lower right corner of the edict, there are two strings of numbers. The first string of numbers is a random string, and the second string of numbers is the result of encrypting the first string of numbers with the private key.

)3) Someone does not believe that this edict is written by the emperor, so they decrypt the second string of numbers using the public key. After decryption, they find that it is the same as the first string of numbers, indicating that it is indeed written by the emperor. Because ordinary people do not have the key, they cannot encrypt data that can be decrypted with the public key.

In this scenario, the public key is used for decryption, and the private key is used for encryption. This can be used to prove that an announcement is indeed sent by a certain person when issuing an announcement. It is equivalent to a signature.

In fact, the signature does not need to be particularly long. Generally, the signature is fixed-length. To achieve fixed length, you can use the MessageDigest algorithm, such as MD5And SHA series. Therefore, there are many signature algorithms, such as MD5withRSA, etc.

RSA encryption/Decryption example

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";
  /**
   * Initialize the key
   * @return
   * @throws Exception
   */
  public static Map<String, Object> initKey() throws Exception{
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);//512-65536 & 64multiple of
    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 the data using the 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 po";
    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);
  }
}

That's all for the content of this article. I hope it will be helpful to everyone's learning and also hope everyone will support the Shout Tutorial more.

Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (when sending an email, please replace # with @ to report, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)

You May Also Like