RSA 非对称加密算法工具类


/**
 * RSA 非对称加密算法工具类
 *
 * @ClassName: RSAUtil
 * @Version: 1.0
 */
public class RSAUtil {

    /**
     * 加密算法
     */
    private static final String KEY_ALGORITHM = "RSA";


    /**
     * RSA位数,采用2048,则加密密文和解密密文需要使用245和256
     */
    private static final Integer INITIALIZE_LENGTH = 2048;

    /**
     * 公钥
     */
    public static String publicKey = "";

    /**
     * 私钥
     */
    public static String privateKey = "";


    /**
     * 生成公钥和私钥
     */
    public static void generateKey() {
        // 1.初始化秘钥
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            // 随机数生成器
            SecureRandom sr = new SecureRandom();
            // 设置秘钥长度
            keyPairGenerator.initialize(INITIALIZE_LENGTH, sr);
            // 开始创建
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 进行转码
            publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());
            // 进行转码
            privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * 私钥匙加密或解密
     *
     * @param: content 需要解密的字符串
     * @param: privateKeyStr 私钥
     * @param: opmode Cipher.DECRYPT_MODE=2  解密
     * @return: 解密后的字符串
     */
    public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) {
        // 私钥要用PKCS8进行处理
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
        KeyFactory keyFactory;
        PrivateKey privateKey;
        Cipher cipher;
        byte[] result;
        String text = null;
        try {
            keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // 还原Key对象
            privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(opmode, privateKey);
            //加密解密
            text = encryptTxt(opmode, cipher, content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return text;
    }

    public static String encryptTxt(int opmode, Cipher cipher, String content) {
        byte[] result;
        String text = null;
        try {
            // 加密
            if (opmode == Cipher.ENCRYPT_MODE) {
                result = cipher.doFinal(content.getBytes());
                text = Base64.encodeBase64String(result);
            } else if (opmode == Cipher.DECRYPT_MODE) {
                // 解密
                result = cipher.doFinal(Base64.decodeBase64(content));
                text = new String(result, StandardCharsets.UTF_8);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return text;
    }

    /**
     * 公钥匙加密或解密
     *
     * @param: content 需要加密的字符串
     * @param: publicKeyStr 公钥字符串
     * @param: opmode Cipher.ENCRYPT_MODE=1  加密
     * @return: 密文
     */
    public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) {
        // 公钥要用X509进行处理
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
        KeyFactory keyFactory;
        PublicKey publicKey;
        Cipher cipher;
        byte[] result;
        String text = null;
        try {
            keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // 还原Key对象
            publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(opmode, publicKey);
            text = encryptTxt(opmode, cipher, content);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return text;
    }


    /**
     * 读取文件中的公钥
     *
     * @return: java.security.PublicKey
     **/
    public static PublicKey getPublicKey(String pathPublicKeyName) {
        String publicKeyStr = FileUtils.getKey(pathPublicKeyName);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
        PublicKey publicKey = null;
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            publicKey = factory.generatePublic(x509EncodedKeySpec);
        } catch (Exception e) {
            e.getMessage();
        }
        return publicKey;
    }


    /**
     * 读取文件中的私钥
     *
     * @param pathPrivateKeyName:
     * @return: java.security.PrivateKey
     **/
    public static PrivateKey getPrivateKey(String pathPrivateKeyName) {
        String privateKeyStr = FileUtils.getKey(pathPrivateKeyName);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
        PrivateKey privateKey = null;
        try {
            KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
            privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (Exception e) {
            e.getMessage();
        }
        return privateKey;
    }

    //测试
    public static void main(String[] args) throws Exception {

        //文件地址 和 文件名
        String path = "D:/demo/";
        String publicFileName = "publicKey.txt";
        String privateFileName = "privateKey.txt";

        // 1. 生成(公钥和私钥)密钥对
        RSAUtil.generateKey();
        System.out.println("公钥:" + RSAUtil.publicKey);
        System.out.println("私钥:" + RSAUtil.privateKey);
        System.out.println("----------公钥加密私钥解密(推荐),非对称加密,公钥保存在客户端,私钥保存在服务端-------------");

        //2、将公钥 私钥 输入到文件中
        FileUtils.saveFile(path + publicFileName, RSAUtil.publicKey.getBytes());
        FileUtils.saveFile(path + privateFileName, RSAUtil.privateKey.getBytes());

        //3、从文件中获取公钥私钥
        String publicKey1 = FileUtils.getKey(path + publicFileName);
        String privateKey1 = FileUtils.getKey(path + privateFileName);

        System.out.println("获取到文件中的公钥:" + publicKey1);
        System.out.println("获取到文件中的私钥:" + privateKey1);

        //4、原始密码
        String textsr = "admin";
        System.out.println("原始密码:" + textsr);

        //5、使用生成的公钥加密
        String encryptByPublic = RSAUtil.encryptByPublicKey(textsr, RSAUtil.publicKey, Cipher.ENCRYPT_MODE);
        System.out.println("公钥加密的密码:" + encryptByPublic);

        //6、使用文件中读取的公钥加密,
        String encryptByPublic1 = RSAUtil.encryptByPublicKey(textsr, publicKey1, Cipher.ENCRYPT_MODE);
        System.out.println("文件中的公钥加密的密码:" + encryptByPublic1);

        //7、使用生成的私钥解密
        String jiemi = RSAUtil.encryptByprivateKey(encryptByPublic, RSAUtil.privateKey, Cipher.DECRYPT_MODE);
        System.out.println("私钥解密:" + jiemi);

        //8、使用文件中读取的私钥解密
        String encryptByPrivate1 = RSAUtil.encryptByprivateKey(encryptByPublic, privateKey1, Cipher.DECRYPT_MODE);
        System.out.println("文件中的私钥解密:" + encryptByPrivate1);
    }

FileUtils

/**
 * @Description: 资源文件上传工具类
 * @ClassName: FileUtils
 */
@Log4j2
public class FileUtils {

    /**
     * @param file 文件
     * @param path 文件存放路径
     * @return
     */
    public static String upload(MultipartFile file, String path) {
        //获取文件名后缀
        String fileLastType = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf("."));
        //生成文件名称
        String newFileName = UUID.randomUUID().toString().replaceAll("-", "");
        // 生成新的文件名
        String realPath = path + "/" + newFileName + fileLastType;
        //使用原文件名
        //String realPath = path + "/" + file.getOriginalFilename();

        File dest = new File(realPath);

        //判断文件父目录是否存在
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdir();
        }

        try {
            //保存文件
            file.transferTo(dest);
            return newFileName + fileLastType;
        } catch (IllegalStateException e) {
            log.error(e);
            return "error";
        } catch (IOException e) {
            log.error(e);
            return "error";
        }

    }


    /**
     * 添加文件
     *
     * @param filename: 文件地址 + 文件名称
     * @param data:     数据
     * @return: void
     **/
    public static void saveFile(String filename, byte[] data) throws Exception {
        if (data != null) {
            File file = new File(filename);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdir();
            }
            if (file.exists()) {
                file.delete();
            }
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data, 0, data.length);
            fos.flush();
            fos.close();
        }
    }


    /**
     * 读取文件内容
     *
     * @param filename: 文件地址 + 文件名称
     * @return: java.lang.String
     **/
    public static String getKey(String filename) {
        StringBuffer sbf = new StringBuffer();
        try {
            BufferedReader in = new BufferedReader(new FileReader(filename));
            String str;
            while ((str = in.readLine()) != null) {
                sbf.append(str);
            }
        } catch (IOException e) {
        }
        return sbf.toString();
    }


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值