Implementation of RSA Encryption Algorithms in java

Keywords: Java network Apache codec

Reproduced from: https://blog.csdn.net/zyhlwzy/article/details/77948195

RSA encryption algorithm is currently the most influential public key encryption algorithm, and is generally considered as one of the best public key schemes. RSA is the first algorithm that can be used for both encryption and digital signature. It can resist all known cryptographic attacks so far. It has been recommended by ISO as a public key data encryption standard. RSA encryption algorithm is based on a very simple number theory fact: it is very easy to multiply two large prime numbers, but it is extremely difficult to factorize the product at that time, so the product can be public as the encryption key.

RSA has two keys, one is public, called public key, and the other is private, called private key.

In public key cryptosystem, the encrypted key (i.e. public key) PK is public information, while the decrypted key (i.e. secret key) SK needs to be kept secret. Encryption algorithm E and decryption algorithm D are also public. Although the decryption key SK is determined by the public key PK, it can not be calculated according to the PK.

It is based on this theory that the famous RSA algorithm appeared in 1978. It usually consists of a pair of RSA keys, one of which is the secret key, which is saved by the user; the other is the public key, which can be disclosed to the public, or even registered in the network server. RSA keys are at least 500 bits long, and 1024 bits are generally recommended. This makes the computation of encryption very heavy. In order to reduce the amount of computation, the traditional encryption method combined with the public key encryption method is often used in transmitting information, that is, the information is encrypted by the improved DES or IDEA dialogue key, and then the RSA key is used to encrypt the dialogue key and information abstract. After receiving the information, the other party decrypts it with different keys and checks the information abstract.

RSA algorithm is the first one that can be used for both encryption and digital signature. It is also easy to understand and operate. RSA is the most widely studied public key algorithm. In the past thirty years, RSA has experienced various attacks and gradually been accepted as one of the best public key schemes.

RSA algorithm is an asymmetric cryptographic algorithm. The so-called asymmetry means that the algorithm needs a pair of keys. If one of them is used to encrypt, the other one is needed to decrypt.

java implementation:

package ron.blog.blog_common.security;

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

public class SecurityRSAUtils {
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

// public key
private static final String PUBLIC_KEY = "RSAPublicKey";
// private key
private static final String PRIVATE_KEY = "RSAPrivateKey";

/**
 * @Comment Base64 Decode
 * @Author Ron
 * @Date 2017 September 12, 4:45:19 p.m.
 * @return
 */
public static byte[] decryptBASE64(String key) {
    return Base64.decodeBase64(key);
}

/**
 * @Comment Base64 Code
 * @Author Ron
 * @Date 2017 September 12, 4:47:55 p.m.
 * @return
 */
public static String encryptBASE64(byte[] bytes) {
    return Base64.encodeBase64String(bytes);
}

/**
 * @Comment Signing content with a private key
 * @Author Ron
 * @Date 2017 September 12, 4:58:10 p.m.
 * @return
 * @throws Exception
 */
public static String sign(byte[] data, String privateKey) throws Exception {
    // Decrypt the private key encoded by Base64
    byte[] keyBytes = decryptBASE64(privateKey);

    // Constructing PKCS8EncodedKeySpec object
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    // Encryption algorithm specified by KEY_ALGORITHM
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

    // Private Key Object
    PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // Generating Digital Signature with Private Key Pair Information
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initSign(priKey);
    signature.update(data);
    return encryptBASE64(signature.sign());
}

/**
 * @Comment Public Key Verification Digital Signature
 * @Author Ron
 * @Date 2017 September 12, 5:09:03 p.m.
 * @return
 */
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
    // Decrypting the public key of Base64 encoding
    byte[] keyBytes = decryptBASE64(publicKey);
    // Constructing the X509EncodedKeySpec object
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

    // Encryption algorithm specified by KEY_ALGORITHM
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

    // Getting public key objects
    PublicKey pubKey = keyFactory.generatePublic(keySpec);

    // Verifying digital signatures with public keys
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initVerify(pubKey);
    signature.update(data);

    // Check whether the signature is normal
    return signature.verify(decryptBASE64(sign));
}

/**
 * @Comment Decrypt data by private key
 * @Author Ron
 * @Date 2017 September 12, 5:16:09 p.m.
 * @return
 */
public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
    // Key decryption
    byte[] keyBytes = decryptBASE64(key);
    // Get the private key
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // Data Decryption
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(data);
}

/**
 * @Comment Decrypt data by private key
 * @Author Ron
 * @Date 2017 September 12, 5:19:39 p.m.
 * @return
 */
public static byte[] decryptByPrivateKey(String data, String key) throws Exception {
    return decryptByPrivateKey(decryptBASE64(data), key);
}

/**
 * @Comment Decrypt data by public key
 * @Author Ron
 * @Date 2017 September 12, 5:20:27 p.m.
 * @return
 */
public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
    // Key decryption
    byte[] keyBytes = decryptBASE64(key);

    // Get the public key
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key pubKey = keyFactory.generatePublic(keySpec);

    // Data Decryption
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.DECRYPT_MODE, pubKey);
    return cipher.doFinal(data);
}

/**
 * @Comment Decrypt data by public key
 * @Author Ron
 * @Date 2017 September 12, 5:26:16 p.m.
 * @return
 */
public static byte[] decryptByPublicKey(String data, String key) throws Exception {
    return decryptByPublicKey(decryptBASE64(data), key);
}

/**
 * @Comment Encryption with public key
 * @Author Ron
 * @Date 2017 September 12, 5:29:31 p.m.
 * @return
 */
public static byte[] encryptByPublicKey(String data, String key) throws Exception {
    // Public key decryption
    byte[] keyBytes = decryptBASE64(key);
    // Obtain the public key
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key publicKey = keyFactory.generatePublic(x509KeySpec);

    // Encryption of data
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    return cipher.doFinal(data.getBytes());
}

/**
 * @Comment Encryption with private key
 * @Author Ron
 * @Date 2017 September 12, 5:34:36 p.m.
 * @return
 */
public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
    // Key decryption
    byte[] keyBytes = decryptBASE64(key);
    // Get the private key
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
    // Encryption of data
    Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);
    return cipher.doFinal(data);
}

/**
 * @Comment Get the private key
 * @Author Ron
 * @Date 2017 September 12, 5:35:16 p.m.
 * @return
 */
public static String getPrivateKey(Map<String, Key> keyMap) throws Exception {
    Key key = (Key) keyMap.get(PRIVATE_KEY);
    return encryptBASE64(key.getEncoded());
}

/**
 * @Comment Get the public key
 * @Author Ron
 * @Date 2017 September 12, 5:35:40 p.m.
 * @return
 */
public static String getPublicKey(Map<String, Key> keyMap) throws Exception {
    Key key = keyMap.get(PUBLIC_KEY);
    return encryptBASE64(key.getEncoded());
}

/**
 * @Comment Initialize key pairs
 * @Author Ron
 * @Date 2017 September 12, 5:36:29 p.m.
 * @return
 */
public static Map<String, Key> initKey() throws Exception {
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
    keyPairGen.initialize(1024);
    KeyPair keyPair = keyPairGen.generateKeyPair();
    Map<String, Key> keyMap = new HashMap(2);
    keyMap.put(PUBLIC_KEY, keyPair.getPublic());// public key
    keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// private key
    return keyMap;
}

public static void main(String[] args) throws Exception {
    Map<String, Key> keyMap = initKey();
    String publicKey = getPublicKey(keyMap);
    String privateKey = getPrivateKey(keyMap);

    System.out.println("--------------------------------------PublicKey------------------------------------------------");
    System.out.println(publicKey);
    System.out.println("--------------------------------------PrivateKey-----------------------------------------------");
    System.out.println(privateKey);

    System.out.println("--------------------------------------secret key encryption-------------------------------------------------");
    byte[] encryptByPrivateKey = encryptByPrivateKey("Ron,Hello, private key encryption".getBytes(),privateKey);
    System.out.println(encryptBASE64(encryptByPrivateKey));

    System.out.println("--------------------------------------Public Key Encryption-------------------------------------------------");
    byte[] encryptByPublicKey = encryptByPublicKey("Ron,Hello, Public Key Encryption",publicKey);
    System.out.println(encryptBASE64(encryptByPublicKey));

    System.out.println("--------------------------------------Private key signature------------------------------------------------");
    String sign = sign(encryptByPrivateKey,privateKey);
    System.out.println(sign);

    System.out.println("--------------------------------------Public Key Verification------------------------------------------------");
    boolean verify = verify(encryptByPrivateKey,publicKey,sign);
    System.out.println(verify);

    System.out.println("--------------------------------------Public key decryption------------------------------------------------");
    byte[] decryptByPublicKey = decryptByPublicKey(encryptByPrivateKey,publicKey);
    System.out.println(new String(decryptByPublicKey));
    System.out.println("--------------------------------------Private key decryption------------------------------------------------");
    byte[] decryptByPrivateKey = decryptByPrivateKey(encryptByPublicKey,privateKey);
    System.out.println(new String(decryptByPrivateKey));
}

}

Posted by nuttycoder on Tue, 23 Jul 2019 03:38:08 -0700