java数字签名

#####工具类

package com.example.demo.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import java.io.InputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/*
 *
 *加密工具类
 * @author jxd
 * @date 2021/2/18 16:45
 * @return
 */
public class EncryptionUtil {
    static Logger logger = LoggerFactory.getLogger(EncryptionUtil.class);

    /**
     * 密钥 键值对 提高访问效率
     * key 密钥key
     * value 密钥value
     */
    private static Map<String, String> keyMap = new HashMap<>();
    /**
     * 签名算法
     */
    private static String signatureKey = "MD5withRSA";
    /**
     * 加密算法
     */
    private static String algorithm = "RSA";


    /**
     * 根据公钥字符串生成公钥对象
     *
     * @param publicKeyStr
     * @param algorithm    RSA  加密算法
     */
    private static PublicKey generatePublicKeyByStr(String publicKeyStr, String algorithm) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        BASE64Decoder base64Decoder = new BASE64Decoder();
        byte[] buffer = base64Decoder.decodeBuffer(publicKeyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
        return rsaPublicKey;
    }

    /**
     * 根据私钥字符串生成私钥对象
     *
     * @param privateKeyStr 私钥字符串
     * @param algorithm     加密算法
     * @return
     * @throws Exception
     */
    private static PrivateKey generatePrivateKeyByStr(String privateKeyStr, String algorithm) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        BASE64Decoder base64Decoder = new BASE64Decoder();
        byte[] buffer = base64Decoder.decodeBuffer(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        return rsaPrivateKey;
    }

    /**
     * 根据字符串生成私钥签名
     *
     * @param string        要签名的内容
     * @param privateKeyStr 私钥字符串
     * @return
     * @throws Exception
     */
    public static String sign(String string, String privateKeyStr) throws Exception {
        PrivateKey privateKey = generatePrivateKeyByStr(privateKeyStr, algorithm);
        Signature signature = Signature.getInstance(signatureKey);
        signature.initSign(privateKey);
        signature.update(string.getBytes());
        byte[] result = signature.sign();
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * 根据签名和公钥字符串验证签名合法性
     *
     * @param sign
     * @param publicKeyStr
     * @param string       要签名的内容
     * @return
     */
    public static boolean verify(String sign, String string, String publicKeyStr) {
        try {
            PublicKey publicKey = generatePublicKeyByStr(publicKeyStr, algorithm);
            Signature signature = Signature.getInstance(signatureKey);
            signature.initVerify(publicKey);
            signature.update(string.getBytes());
            //重点 一点要解密
            boolean bool = signature.verify(Base64.getDecoder().decode(sign));
            return bool;
        } catch (Exception e) {
            logger.error("", e);
            return false;
        }
    }

    /**
     * 根据问价路径读取文件内容
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static String getFileByFilePath(String filePath) throws Exception {
        if (keyMap.containsKey(filePath)) {
            logger.info("{} 从缓存中读取...", filePath);
            return keyMap.get(filePath);
        }
        InputStream in = EncryptionUtil.class.getClassLoader().getResourceAsStream(filePath);
        StringBuilder stringBuilder = new StringBuilder();
        byte[] bytes = new byte[1024];
        int count;
        while ((count = in.read(bytes)) != -1) {
            stringBuilder.append(new String(bytes, 0, count));
        }
        keyMap.put(filePath, stringBuilder.toString());
        logger.info("{} 第一次读取...", filePath);
        return stringBuilder.toString();
    }

    /**
     * 公钥加密
     *
     * @param data 待加密数据
     * @param key  密钥 Base64加密后的密钥字符串
     * @return Base64处理后的加密数据
     */
    public static String encryptByPublicKey(String data, String key) throws Exception {

        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        //初始化公钥
        //产生公钥
        PublicKey pubKey = generatePublicKeyByStr(key, algorithm);
        //数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        byte[] result = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(result);
    }


    /**
     * 私钥解密
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return byte[] 解密数据
     */
    public static String decryptByPrivateKey(String data, String key) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        //生成私钥
        PrivateKey privateKey = generatePrivateKeyByStr(key, algorithm);
        //数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(data));
        return new String(result);
    }

    /**
     * 私钥加密
     *
     * @param data 待加密数据
     * @param key  密钥
     * @return byte[] 加密数据
     */
    public static String encryptByPrivateKey(String data, String key) throws Exception {

        //取得私钥
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        //生成私钥
        PrivateKey privateKey = generatePrivateKeyByStr(key, algorithm);
        //数据加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * 公钥解密
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return byte[] 解密数据
     */
    public static String decryptByPublicKey(String data, String key) throws Exception {

        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        //初始化公钥

        //产生公钥
        PublicKey pubKey = generatePublicKeyByStr(key, algorithm);
        //数据解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(data));
        return new String(result);
    }

    /**
     * 生成公私钥对
     *
     * @throws Exception
     */
    public static void generatePubPrivateKey() throws Exception {
        KeyPairGenerator pair = KeyPairGenerator.getInstance(algorithm);
        KeyPair pp = pair.generateKeyPair();
        //生成私钥
        PrivateKey privateKey = pp.getPrivate();
        //生成公钥
        PublicKey publicKey = pp.getPublic();
        byte[] privateKeyEncoded = privateKey.getEncoded();
        byte[] publicKeyEncoded = publicKey.getEncoded();
        System.out.println("私钥:");
        System.out.println(com.sun.org.apache.xml.internal.security.utils.Base64.encode(privateKeyEncoded));
        System.out.println("公钥:");
        System.out.println(com.sun.org.apache.xml.internal.security.utils.Base64.encode(publicKeyEncoded));
    }
}

#####测试:

package com.example.mydemo.jiami;

import com.example.mydemo.util.EncryptionUtil;


/**
 * 数字签名测试
 */
public class App {
    public static void main(String[] args) throws Exception {
        EncryptionUtil dig = new EncryptionUtil();
        String privatekeyStr = dig.getFileByFilePath("privatekey");
        String publickeyStr = dig.getFileByFilePath("publickey");
        String string = "哈哈哈";
        String sign = EncryptionUtil.sign(string, privatekeyStr);
        System.out.println("签名:");
        System.out.println(sign);
        System.out.println("----");
        boolean flag = EncryptionUtil.verify(sign, string, publickeyStr);
        System.out.println("验证签名结果:");
        System.out.println(flag);

        EncryptionUtil.generatePubPrivateKey();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JAVA-葵花宝典

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值