RSA加密算法是一种非对称加密算法,在公开密钥加密和电子商业中RSA被广泛使用。

RSAUtil.java

/**
 * RSA加密工具类
 *
 * @author yuyuko
 */
public final class RSAUtil {
    /**
     * 加密算法
     */
    public static final String ALGORITHM = "RSA";
    /**
     * 加密标准
     */
    public static final String ENCRYPTIONSTANDARD = "RSA/ECB/PKCS1Padding";

    /**
     * 签名算法
     */
    public static final String VERIFY = "MD5withRSA";
    /**
     * 密钥长度1024
     */
    public static final int LENGTH1024 = 1204;
    /**
     * 密钥长度2048
     */
    public static final int LENGTH2048 = 2048;
    /**
     * 密钥长度4096
     */
    public static final int LENGTH4096 = 4096;

    private RSAUtil() {

    }
}

RsaKey.java

/**
 * 生成密钥对
 *
 * @author yuyuko
 */
public class RsaKey {
    private PrivateKey privateKey;
    private PublicKey publicKey;

    /**
     * 生成的密钥长度
     *
     * @param keyLength 密钥长度
     * @throws NoSuchAlgorithmException NoSuchAlgorithmException
     */
    public RsaKey(int keyLength) throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(keyLength);
        KeyPair pair = keyGen.generateKeyPair();
        this.privateKey = pair.getPrivate();
        this.publicKey = pair.getPublic();
    }

    /**
     * 写入文件
     *
     * @param path 路径
     * @param key  密钥
     * @throws IOException  IOException
     */
    public void writeToFile(String path, byte[] key) throws IOException {
        File f = new File(path);
        f.getParentFile().mkdirs();
        FileOutputStream fos = new FileOutputStream(f);
        fos.write(key);
        fos.flush();
        fos.close();
    }

    /**
     * 私钥
     *
     * @return string
     */
    public String getPrivateKeyStr() {
        return Base64.getEncoder().encodeToString(this.privateKey.getEncoded());
    }

    /**
     * 公钥
     *
     * @return string
     */
    public String getpublicKeyStr() {
        return Base64.getEncoder().encodeToString(this.publicKey.getEncoded());
    }

    public PrivateKey getPrivateKey() {
        return privateKey;
    }

    public PublicKey getPublicKey() {
        return publicKey;
    }
}

RSAEncrypt.java

/**
 * RSA加密
 *
 * @author yuyuko
 */
public class RSAEncrypt {


    /**
     * 公钥
     *
     * @param base64PublicKey 公钥Key
     * @return PublicKey
     */
    private static PublicKey getPublicKey(String base64PublicKey) {
        PublicKey publicKey;
        try {
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));
            KeyFactory keyFactory = KeyFactory.getInstance(RSAUtil.ALGORITHM);
            publicKey = keyFactory.generatePublic(keySpec);
            return publicKey;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 私钥
     *
     * @param base64PrivateKey 私钥Key
     * @return PrivateKey
     */
    private static PrivateKey getPrivateKey(String base64PrivateKey) {
        PrivateKey privateKey;
        try {
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes()));
            KeyFactory keyFactory = KeyFactory.getInstance(RSAUtil.ALGORITHM);
            privateKey = keyFactory.generatePrivate(keySpec);
            return privateKey;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公钥加密
     *
     * @param data      需要加密的数据
     * @param publicKey 公钥
     * @return 加密后的二进制数据
     * @throws NoSuchPaddingException    NoSuchPaddingException
     * @throws NoSuchAlgorithmException  NoSuchAlgorithmException
     * @throws BadPaddingException       BadPaddingException
     * @throws IllegalBlockSizeException IllegalBlockSizeException
     * @throws InvalidKeyException       InvalidKeyException
     */
    public static byte[] encryptPublic(String data, String publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(RSAUtil.ENCRYPTIONSTANDARD);
        cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey));
        return cipher.doFinal(data.getBytes());
    }

    /**
     * 私钥加密
     *
     * @param data       需要加密的数据
     * @param privateKey 私钥
     * @return 加密后的二进制数据
     * @throws NoSuchPaddingException    NoSuchPaddingException
     * @throws NoSuchAlgorithmException  NoSuchAlgorithmException
     * @throws BadPaddingException       BadPaddingException
     * @throws IllegalBlockSizeException IllegalBlockSizeException
     * @throws InvalidKeyException       InvalidKeyException
     */
    public static byte[] encryptPrivate(String data, String privateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException {
        Cipher cipher = Cipher.getInstance(RSAUtil.ENCRYPTIONSTANDARD);
        cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(privateKey));
        return cipher.doFinal(data.getBytes());
    }

    /**
     * 私钥签名
     *
     * @param data       签名数据
     * @param privateKey 私钥
     * @return Base64编码
     * @throws NoSuchAlgorithmException NoSuchAlgorithmException
     * @throws InvalidKeySpecException  InvalidKeySpecException
     * @throws InvalidKeyException      InvalidKeyException
     * @throws SignatureException       SignatureException
     */
    public static String sign(byte[] data, byte[] privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);
        KeyFactory keyFactory = KeyFactory.getInstance(RSAUtil.ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        //签名算法
        Signature signature = Signature.getInstance(RSAUtil.VERIFY);
        signature.initSign(privateK);
        signature.update(data);
        return Base64.getEncoder().encodeToString(signature.sign());
    }

    /**
     * 私钥签名
     *
     * @param data       签名数据
     * @param privateKey 私钥
     * @return Base64编码
     * @throws NoSuchAlgorithmException NoSuchAlgorithmException
     * @throws InvalidKeySpecException  InvalidKeySpecException
     * @throws InvalidKeyException      InvalidKeyException
     * @throws SignatureException       SignatureException
     */
    public static String sign(String data, String privateKey) throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        return sign(Base64.getDecoder().decode(data), Base64.getDecoder().decode(privateKey));
    }
}

RSADecrypt.java

/**
 * RSA解密
 *
 * @author yuyuko
 */
public class RSADecrypt {
    /**
     * 私钥
     *
     * @param base64PrivateKey 私钥
     * @return PrivateKey
     */
    private static PrivateKey getPrivateKey(String base64PrivateKey) {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes()));
        KeyFactory keyFactory;
        PrivateKey privateKey = null;
        try {
            keyFactory = KeyFactory.getInstance(RSAUtil.ALGORITHM);
            privateKey = keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return privateKey;
    }

    /**
     * 公钥
     *
     * @param base64PublicKey 公钥
     * @return PublicKey
     */
    private static PublicKey getPublicKey(String base64PublicKey) {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));
        KeyFactory keyFactory;
        PublicKey publicKey = null;
        try {
            keyFactory = KeyFactory.getInstance(RSAUtil.ALGORITHM);
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return publicKey;
    }

    /**
     * 私钥解密
     *
     * @param data       加密后的数据
     * @param privateKey 私钥
     * @return 解密后的数据
     * @throws NoSuchPaddingException    NoSuchPaddingException
     * @throws NoSuchAlgorithmException  NoSuchAlgorithmException
     * @throws InvalidKeyException       InvalidKeyException
     * @throws BadPaddingException       BadPaddingException
     * @throws IllegalBlockSizeException IllegalBlockSizeException
     */
    public static String decryptPrivateKey(byte[] data, PrivateKey privateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(RSAUtil.ENCRYPTIONSTANDARD);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(cipher.doFinal(data));
    }

    /**
     * 私钥解密
     *
     * @param data             加密后的数据
     * @param base64PrivateKey 私钥
     * @return 解密后的数据
     * @throws NoSuchPaddingException    NoSuchPaddingException
     * @throws NoSuchAlgorithmException  NoSuchAlgorithmException
     * @throws InvalidKeyException       InvalidKeyException
     * @throws BadPaddingException       BadPaddingException
     * @throws IllegalBlockSizeException IllegalBlockSizeException
     */
    public static String decryptPrivateKey(String data, String base64PrivateKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        return decryptPrivateKey(Base64.getDecoder().decode(data), getPrivateKey(base64PrivateKey));
    }

    /**
     * 公钥解密
     *
     * @param data      加密后的数据
     * @param publicKey 公钥
     * @return 解密后的数据
     * @throws NoSuchPaddingException    NoSuchPaddingException
     * @throws NoSuchAlgorithmException  NoSuchAlgorithmException
     * @throws InvalidKeyException       InvalidKeyException
     * @throws BadPaddingException       BadPaddingException
     * @throws IllegalBlockSizeException IllegalBlockSizeException
     */
    public static String decryptPublicKey(byte[] data, PublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance(RSAUtil.ENCRYPTIONSTANDARD);
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return new String(cipher.doFinal(data));
    }

    /**
     * 公钥解密
     *
     * @param data            加密后的数据
     * @param base64PublicKey 公钥
     * @return 解密后的数据
     * @throws NoSuchPaddingException    NoSuchPaddingException
     * @throws NoSuchAlgorithmException  NoSuchAlgorithmException
     * @throws InvalidKeyException       InvalidKeyException
     * @throws BadPaddingException       BadPaddingException
     * @throws IllegalBlockSizeException IllegalBlockSizeException
     */
    public static String decryptPublicKey(String data, String base64PublicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        return decryptPublicKey(Base64.getDecoder().decode(data), getPublicKey(base64PublicKey));
    }

    /**
     * 效验数字签名
     *
     * @param encryptPrivate 加密后的字符串
     * @param publicKey      公钥
     * @param sign           数字签名
     * @return 效验结果
     * @throws NoSuchAlgorithmException NoSuchAlgorithmException
     * @throws InvalidKeySpecException  InvalidKeySpecException
     * @throws InvalidKeyException      InvalidKeyException
     * @throws SignatureException       SignatureException
     */
    public static boolean verify(byte[] encryptPrivate, byte[] publicKey, byte[] sign) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
        KeyFactory keyFactory = KeyFactory.getInstance(RSAUtil.ALGORITHM);
        PublicKey publicKey1 = keyFactory.generatePublic(keySpec);
        //签名算法
        Signature signature = Signature.getInstance(RSAUtil.VERIFY);
        signature.initVerify(publicKey1);
        signature.update(encryptPrivate);
        return signature.verify(sign);
    }

    /**
     * 效验数字签名
     *
     * @param encryptPrivate 加密后的字符串
     * @param publicKey      公钥
     * @param sign           数字签名
     * @return 效验结果
     * @throws NoSuchAlgorithmException NoSuchAlgorithmException
     * @throws InvalidKeySpecException  InvalidKeySpecException
     * @throws InvalidKeyException      InvalidKeyException
     * @throws SignatureException       SignatureException
     */
    public static boolean verify(String encryptPrivate, String publicKey, String sign) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
        return verify(Base64.getDecoder().decode(encryptPrivate), Base64.getDecoder().decode(publicKey), Base64.getDecoder().decode(sign));
    }
}

编写测试类,测试:

public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        try {
            String password = "123456";
            System.out.println("密码:" + password);
            RsaKey rsaKey = new RsaKey(RSAUtil.LENGTH4096);
            String privateKey = rsaKey.getPrivateKeyStr();
            String publicKey = rsaKey.getpublicKeyStr();
            System.out.println("RSA-privateKey===>>>>>>" + privateKey);
            System.out.println("RSA-publicKey===>>>" + publicKey);
            //公钥加密
            String encryptPublic = Base64.getEncoder().encodeToString(RSAEncrypt.encryptPublic(password, publicKey));
            System.out.println("RSA-public-encrypt===>>>" + encryptPublic);
            //私钥解密
            String decryptStr = RSADecrypt.decryptPrivateKey(encryptPublic, privateKey);
            System.out.println("RSA-private-decrypt===>>>" + decryptStr);
            //私钥签名
            String privtaeSignature = Base64.getEncoder().encodeToString(RSAEncrypt.encryptPrivate(password, privateKey));
            String md5Signature = RSAEncrypt.sign(privtaeSignature, privateKey);
            System.out.println("RSA-private-signature===>>>" + md5Signature);
            //公钥验证签名
            System.out.println("RSA-public-verificationSignature===>>>" + RSADecrypt.verify(privtaeSignature, publicKey, md5Signature));
            //公钥解密
            String publicVerificationSignature = RSADecrypt.decryptPublicKey(privtaeSignature, publicKey);
            System.out.println("RSA-public-decrypt===>>>" + publicVerificationSignature);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


翻开的童话书里,写的是我的愿望和梦境。这次,是不是终于可以握紧你的手,和你永不分离。