[Java tools] Asymmetric encryption using RSA algorithm serialization save processing public key private key encryption and decryption tools

The following java serialization will output the public key and private key to the files PublicKey, PrivateKey and save it. Encryption and decryption must deserialize the file into a Java byte stream, and then perform the corresponding processing.

  • Since the encrypted ciphertexts are all in bytecode form, if we want to save or transmit as a string, we can useBase64编码算法
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * 使用java的序列化保存处理公钥私钥加解密
 */
public class RSASerializationUtil {
    
    
    /**
     * 指定加密算法为RSA
     */
    private static final String ALGORITHM = "RSA";
    /*指定加密模式和填充方式*/
    private static final String ALGORITHM_MODEL = "RSA/ECB/PKCS1Padding";
    /**指定key的大小,一般为1024,越大安全性越高*/
    private static final  int KEYSIZE = 1024;
    /**指定公钥存放文件*/
    private static final String PUBLIC_KEY_FILE = "PublicKey";
    /**指定私钥存放文件*/
    private static  final String PRIVATE_KEY_FILE = "PrivateKey";




    /**
     * 从base64编码的公钥恢复公钥
     * @param key_base64
     * @return
     * @throws Exception
     */
    public PublicKey getPulbickey(String key_base64) throws Exception{
    
    
        byte[] pb =  Base64.getDecoder().decode(key_base64);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pb);
        KeyFactory  keyfactory = KeyFactory.getInstance(ALGORITHM);
        return keyfactory.generatePublic(keySpec);
    }

    /**
     * 从base64编码的私钥恢复私钥
     * @param key_base64
     * @return
     * @throws Exception
     */
    public PrivateKey getPrivatekey(String key_base64) throws Exception{
    
    
        byte[] pb =  Base64.getDecoder().decode(key_base64);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pb);
        KeyFactory  keyfactory = KeyFactory.getInstance(ALGORITHM);
        return keyfactory.generatePrivate(keySpec);
    }

    //从base64编码的特征值(N,e)恢复公钥
    public static PublicKey getPulbickey(String N_Str,String e_Str) throws Exception{
    
    
        BigInteger N = new BigInteger(1, Base64.getDecoder().decode(N_Str.getBytes()));
        BigInteger e = new BigInteger(1, Base64.getDecoder().decode(e_Str.getBytes()));
        KeyFactory kf = KeyFactory.getInstance(ALGORITHM);
        RSAPublicKeySpec ps = new RSAPublicKeySpec(N, e);
        PublicKey pkey = kf.generatePublic(ps);
        return pkey;
    }
    //从base64编码的特征值(N,d)恢复私钥
    public static PrivateKey getPrivatekey(String N_Str,String d_Str) throws Exception{
    
    
        BigInteger N = new BigInteger(1,  Base64.getDecoder().decode(N_Str.getBytes()));
        BigInteger d = new BigInteger(1,  Base64.getDecoder().decode(d_Str.getBytes()));
        KeyFactory kf = KeyFactory.getInstance(ALGORITHM);
        RSAPrivateKeySpec ps = new RSAPrivateKeySpec(N, d);
        PrivateKey pkey = kf.generatePrivate(ps);
        return pkey;
    }

    /**
     * 提取特征值保存,以base64编码密钥
     *
     * @return
     * @throws Exception
     */
    public static Map<String ,String> generateKeyPair2() throws Exception{
    
    
        SecureRandom sr = new SecureRandom();
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(1024, sr);
        KeyPair kp = kpg.generateKeyPair();
        Key publicKey = kp.getPublic();
        Key privateKey = kp.getPrivate();
        RSAPublicKey rpk = (RSAPublicKey)publicKey;
        RSAPrivateKey rpr= (RSAPrivateKey)privateKey;
        //三个特征值都是BigInteger类型。
        BigInteger N = rpk.getModulus();//N值
        BigInteger e = rpk.getPublicExponent();//e值
        BigInteger d  = rpr.getPrivateExponent();//d值
        Map<String, String> map = new HashMap<String, String>();
        //将BigInteger转为byte[],然后以base64保存
        map.put("N",new String(Base64.getDecoder().decode(N.toByteArray())));
        map.put("e", new String(Base64.getDecoder().decode(e.toByteArray())));
        map.put("d", new String(Base64.getDecoder().decode(d.toByteArray())));
        return map;
    }


    /**
     * 以base64编码密钥
     *
     * 通过密钥生成器生成公钥,私钥后,调用publicKey.getEncoded()和privateKey.getEncoded(),此时它生成的比特编码是有独特格式的(公钥是X.509,私钥是PKCS#8)可以使用publicKey.getFormat(),privateKey.getFormat();进行查看。之后对字节码进行Base64编码就行了。
     */
    public Map<String ,String> generateKeyPairMap() throws Exception{
    
    
        /** RSA算法要求有一个可信任的随机数源 */
        SecureRandom sr = new SecureRandom();
        /** 为RSA算法创建一个KeyPairGenerator对象 */
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
        /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
        kpg.initialize(KEYSIZE, sr);
        /** 生成密匙对 */
        KeyPair kp = kpg.generateKeyPair();
        /** 得到公钥 */
        Key publicKey = kp.getPublic();
        /** 得到私钥 */
        Key privateKey = kp.getPrivate();

        //公钥字节
        byte[] pb = publicKey.getEncoded();
        //由于加密后的密文都是字节码形式的,我们要以字符串方式保存或传输的话,可以使用Base64编码。
        String pbStr = Base64.getEncoder().encodeToString(pb);
        //私钥字节
        byte[] pr = privateKey.getEncoded();
        String prStr = Base64.getEncoder().encodeToString(pr);

        Map<String, String> map = new HashMap<>();
        map.put(PUBLIC_KEY_FILE,pbStr);
        map.put(PRIVATE_KEY_FILE, prStr);
        return map;
    }

    /**序列化生成密钥对*/
    private static void generateKeyPair() throws Exception {
    
    
        /** RSA算法要求有一个可信任的随机数源 */
        SecureRandom sr = new SecureRandom();
        /** 为RSA算法创建一个KeyPairGenerator对象 */
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
        /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
        kpg.initialize(KEYSIZE, sr);
        /** 生成密匙对 */
        KeyPair kp = kpg.generateKeyPair();
        /** 得到公钥 */
        Key publicKey = kp.getPublic();
        /** 得到私钥 */
        Key privateKey = kp.getPrivate();
        /** 用对象流将生成的密钥写入文件 */
        ObjectOutputStream publicOOS = new ObjectOutputStream(new FileOutputStream(
                PUBLIC_KEY_FILE));
        ObjectOutputStream privateOOS = new ObjectOutputStream(new FileOutputStream(
                PRIVATE_KEY_FILE));
        publicOOS.writeObject(publicKey);
        privateOOS.writeObject(privateKey);
        /** 清空缓存,关闭文件输出流 */
        publicOOS.close();
        privateOOS.close();
    }

    /**加密方法 source: 源数据*/
    public static byte[] encrypt(String source) throws Exception {
    
    

        /** 将文件中的公钥对象读出 */
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                PUBLIC_KEY_FILE));
        Key key = (Key) ois.readObject();
        ois.close();
        /** 得到Cipher对象来实现对源数据的RSA加密 */
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODEL);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] b = source.getBytes();
        /** 执行加密操作 */
        return cipher.doFinal(b);
    }

    /**解密算法 cryptograph:密文*/
    public static String decrypt(byte[] cryptograph) throws Exception {
    
    
        /** 将文件中的私钥对象读出 */
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                PRIVATE_KEY_FILE));
        Key key = (Key) ois.readObject();
        /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODEL);
        cipher.init(Cipher.DECRYPT_MODE, key);
        /** 执行解密操作 */
        byte[] bytes = cipher.doFinal(cryptograph);
        return new String(bytes);
    }

    public static void main(String[] args) throws Exception {
    
    
        //生成密钥对
        generateKeyPair();

        // 要加密的字符串
        String source = "Hello World!";

        // 生成的密文
        byte[] cryptograph = encrypt(source);

        //可以将密文进行base64编码进行传输
        System.out.println(Base64.getEncoder().encodeToString(cryptograph));

        // 解密密文
        String target = decrypt(cryptograph);
        System.out.println(target);
    }
}

main method execution result

dQzpKmKcQJkQqBLvCeO/9SWid+9GwaTljOXDRWojhmgUQXxTcvYsbi4QlEk643SiJkMpbqjnT/oCq08aur9FIu5eF2QhxlrH/A+OiA4GyG3kEe/ZTXbUwDeNnxiQc5UeWLX2U3yZZp0YHZe3MNKkjRoFq6L2co1+Pmp3C/qIsLE=
Hello World!

Guess you like

Origin blog.csdn.net/qq877728715/article/details/115213016