RSA非对称加密算法工具类

  • 使用私有CA签发用户证书
    step[1]私钥还不能直接被使用,需要进行PKCS#8编码step[5]:openssl pkcs8 -topk8 -in rsa_private_key.key -out pkcs8_rsa_private_key.key -nocrypt
import cn.lettin.bean.response.QueryLettinTerritoryListResponseVo;
import cn.lettin.exception.GlobalException;
import cn.lettin.mapper.LettinTerritoryMapper;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.lettin.exception.GlobalException.CREATE_CERT_ERROR;

@Slf4j
public class CertificateUtil {

    /**
     * 更新用户证书
     *
     * @param certBasePath
     * @param userId
     * @param lettinTerritoryMapper
     * @return
     * @throws GlobalException
     */
    public static String updateUserCertificate(String certBasePath, int userId, LettinTerritoryMapper lettinTerritoryMapper) throws GlobalException {
        Map<String, String> userGwAuth = new HashMap<>();
        List<QueryLettinTerritoryListResponseVo.TerritoryInfo> territoryInfos = lettinTerritoryMapper.queryLettinUserTerritoryByUserId(userId);
        for (QueryLettinTerritoryListResponseVo.TerritoryInfo territoryInfo : territoryInfos) {
            if (territoryInfo.getStatus()) {
                List<String> gwIdList = lettinTerritoryMapper.queryLettinTerritoryGatewayByTerritoryId(territoryInfo.getTerritoryId());
                for (String gatewayId : gwIdList) {
                    userGwAuth.put(gatewayId, String.valueOf(territoryInfo.getRoleId()));
                }
            }
        }
        return createCertificate(certBasePath, userId, userGwAuth, 36500);
    }

    /**
     * @param certBasePath 基础路径
     * @param userId       用户id
     * @param userGwAuth   用户可用网关权限
     * @param days         证书有效天数
     * @return 证书路径
     */
    public static String createCertificate(String certBasePath, int userId, Map<String, String> userGwAuth, int days) throws GlobalException {
        String crtName = userId + "_certificate";                              //证书名
        String pass = UniqIdUtils.getInstance().getUniqIDHashString();        //私钥密码
        String cACrtPath = certBasePath + "CA/ca";                           //根证书路径带文件名,没有文件后缀.crt .key .csr
        String userPath = certBasePath + userId + "/";                      //用户的资源路径
        String clientCrtPath = userPath + crtName;                         //客户端证书路径带文件名,没有文件后缀.crt .key .csr
        String opensslPath = certBasePath + "openssl.cnf";
        JSONObject ou = new JSONObject();
        ou.put("userId", userId);
        ou.put("timestamp", System.currentTimeMillis());
        ou.put("userGwAuth", userGwAuth);
        System.out.println(ou.toJSONString());
        System.out.println(ou.toJSONString().length());
        String[] step = new String[6];
        step[0] = "mkdir -p " + userPath;
        step[1] = "openssl genrsa -aes256 -passout pass:" + pass + " -out " + clientCrtPath + ".key 2048";
        step[2] = "openssl rsa -in  " + clientCrtPath + ".key -passin pass:" + pass + " -out " + clientCrtPath + ".key";
        step[3] = "openssl req -new -key " + clientCrtPath + ".key -out " + clientCrtPath + ".csr -config " + opensslPath + " -subj /C=AU/ST=Some-State/O=Lettin/CN=dev/OU=Accle";
        step[4] = "yes yes|openssl ca -in " + clientCrtPath + ".csr -out " + clientCrtPath + ".crt -cert " + cACrtPath + ".crt -keyfile " + cACrtPath + ".key -config " + opensslPath + " -days " + days;
        step[5] = "openssl pkcs8 -topk8 -in " + clientCrtPath + ".key -out " + clientCrtPath + "_rsa.key -nocrypt";
        String[] cmd = {"sh", "-c", ""};
        Process ps = null;
        try {
            for (int i = 0; i < step.length; i++) {
                if (i == 0) {
                    File file = new File(userPath);
                    if (file.exists()) {
                        continue;
                    }
                }
                cmd[2] = step[i];
                log.info("执行命令: {}", cmd[2]);
                ps = Runtime.getRuntime().exec(cmd);
                int waitFor = ps.waitFor();
                ps.destroy();
                ps = null;
                if (waitFor != 0) {
                    throw new GlobalException(CREATE_CERT_ERROR);
                }
            }
            return clientCrtPath + ".crt";
        } catch (Exception e) {
            log.error("证书创建失败: {}", cmd[2]);
            throw new GlobalException(CREATE_CERT_ERROR.setMessage(e.getMessage()));
        } finally {
            if (ps != null) {
                ps.destroy();
            }
        }
    }
}
  • RSA非对称加密算法工具类
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @Description :  封装同RSA非对称加密算法有关的方法,可用于数字签名,RSA加密解密
 * @Author :  ZhangYunXin
 * @CreateDate :  2020/6/1 15:50
 * @UpdateUser :  ZhangYunXin
 * @UpdateDate :  2020/6/1 15:50
 * @UpdateRemark :  新建
 */
public class RSAUtils {

    /**
     * 新建密钥对(公私钥对)
     *
     * @return KeyPair对象
     */
    public static KeyPair creatmyKey() throws Exception {
        long mySeed = System.currentTimeMillis();
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
        random.setSeed(mySeed);
        keyGen.initialize(1024, random);
        KeyPair myPair = keyGen.generateKeyPair();
        return myPair;
    }

    /**
     * 使用RSA私钥加密数据
     *
     * @param privKeyInByte byte[]形式私钥
     * @param data          要加密的数据
     * @return 加密数据
     * @throws Exception
     */
    public static byte[] encryptByPrivKey(byte[] privKeyInByte, byte[] data) throws Exception {
        PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(privKeyInByte);
        KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
        Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privKey);
        return cipher.doFinal(data);
    }

    /**
     * 使用RSA公钥加密数据
     *
     * @param pubKeyInByte byte[]形式公钥
     * @param data         要加密的数据
     * @return 加密数据
     * @throws Exception
     */
    public static byte[] encryptByPubKey(byte[] pubKeyInByte, byte[] data) throws Exception {
        KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
        PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    /**
     * 用RSA公钥解密
     *
     * @param pubKeyInByte
     * @param data
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPubKey(byte[] pubKeyInByte, byte[] data) throws Exception {
        KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
        PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
        Cipher cipher = Cipher.getInstance(mykeyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

    /**
     * 用RSA私钥解密
     *
     * @param privKeyInByte byte[]形式的私钥
     * @param data          要解密的数据
     * @return 解密数据
     * @throws Exception
     */
    public static byte[] decryptByPrivKey(byte[] privKeyInByte, byte[] data) throws Exception {
        PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(privKeyInByte);
        KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privKey);
        return cipher.doFinal(data);
    }

    /**
     * 验证数字签名
     *
     * @param pubKeyInByte byte[]形式的公钥
     * @param source       原文的数字摘要
     * @param sign         签名(对原文的数字摘要的签名)
     * @return 是否证实 boolean
     * @throws Exception
     */
    public static boolean verify(byte[] pubKeyInByte, byte[] source, byte[] sign) throws Exception {
        KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
        Signature sig = Signature.getInstance("SHA1withRSA");
        X509EncodedKeySpec pub_spec = new X509EncodedKeySpec(pubKeyInByte);
        PublicKey pubKey = mykeyFactory.generatePublic(pub_spec);
        sig.initVerify(pubKey);
        sig.update(source);
        return sig.verify(sign);
    }

    /**
     * 使用私钥加密数据,生成数据签名
     * 用一个byte[]形式的私钥加密数据,即数字签名
     *
     * @param privKeyInByte byte[]的私钥
     * @param source        要签名的数据,一般应是数字摘要
     * @return 签名 byte[]
     * @throws Exception
     */
    public static byte[] sign(byte[] privKeyInByte, byte[] source) throws Exception {
        PKCS8EncodedKeySpec priv_spec = new PKCS8EncodedKeySpec(privKeyInByte);
        KeyFactory mykeyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privKey = mykeyFactory.generatePrivate(priv_spec);
        Signature sig = Signature.getInstance("SHA1withRSA");
        sig.initSign(privKey);
        sig.update(source);
        return sig.sign();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值