一文搞懂RSA非对称加密(2)--公钥加密、私钥解密、私钥签名、公钥验签

335 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情 >>

加密过程:

甲方请求乙方,甲方生成秘钥对 将公钥给乙方,乙方生成秘钥对,将公钥给了甲方,现甲方有自己的秘钥对和乙方的公钥,同理现乙方有自己的秘钥对和甲方的公钥

场景一:

甲方请求乙方: 甲方需用乙方的公钥加密数据,并用自己的私钥生成签名,在乙方接受到请求时,乙方需要先验签,乙方通过甲方的公钥验签和自己的私钥解密数据

场景二:

已方请求甲方: 乙方需用甲方的公钥加密数据,并用自己的私钥生成签名,在甲方接受到请求时,甲方需要先验签,甲方通过乙方的公钥验签和自己的私钥解密数据

代码实例

私钥解密,公钥验签

String decrypt = DataDecryptUtil.callfackDecrypt(httpEntity.getData(), httpEntity.getKey(), httpEntity.getSign(), gatewayConfig.g7PublicKey, gatewayConfig.privateKey);

    public static String callfackDecrypt(String response, String envelope, String sign, String publicKey, String privateKey) throws Exception {
        log.info("原始返回结果为:{}, 数字信封为: {}, 签名为: {}", response, envelope, sign);
        PrivateKey privateKeyEnvelop = RsaUtil.getPrivate(privateKey);
        PublicKey publicKeyEnvelop = RsaUtil.getPublicKey(publicKey);
        String deData = null;
        if (!StringUtils.isEmpty(response)) {
            Boolean verify = RsaUtil.verify(response, sign, publicKeyEnvelop)
            //用商户私钥对数字信封解密生成AES秘钥
            String aseKey = RsaUtil.rsaDecrypt(envelope, privateKeyEnvelop);
            log.info("用商户私钥对数字信封解密生成AES秘钥:{}", aseKey);
            if (verify) {
                //用AES秘钥对返回数据做解密
                deData = AesUtil.aesDecrypt(response, aseKey);
                log.info("用AES秘钥对返回数据做解密:{}", deData);
//                jsonObject = JSONObject.parseObject(deData);
                log.info("原始响应:{},data解密后响应:{},验签结果:{}", response, deData, sign);
            } else {

            }
        }
        return deData;
    }

公钥加密,私钥生成签名

JSONObject encryptData;
try {
    rootData = new String(rootData.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
    String envelopOriginal = AesUtil.getRandomAesKey();
    log.info("随机生成的Aes:{}", envelopOriginal);
    PublicKey publicKeyEnvelop = RsaUtil.getPublicKey(gatewayConfig.g7PublicKey);
    //使用对方的公钥加密
    String envelop = RsaUtil.rsaEncrypt(envelopOriginal, publicKeyEnvelop);
    log.info("使用平台公钥对Aes加密生成数字信封:{}", envelop);
    encryptData = DataEncryptUtil.encrypt(rootData, envelopOriginal, envelop,gatewayConfig.privateKey);
} catch (Exception e) {
    e.printStackTrace();
    log.error("加密异常:" + e.getMessage());
    throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "响应体加密异常");
}
    public static JSONObject encrypt(String data, String envelopOriginal, String envelop, String privateKey) throws Exception {
        try {
            log.info("加密开始");
            PrivateKey privateKeyEnvelop = RsaUtil.getPrivate(privateKey);
            JSONObject json = new JSONObject();
            if (!StringUtils.isEmpty(data)) {
                //用AES秘钥对返回数据做解密
                log.info("加解密");
                String deData = AesUtil.aesEncrypt(data, envelopOriginal);
                log.info("签名");
                String sign = RsaUtil.sign(deData, privateKeyEnvelop);
                json.put("data", deData);
                json.put("sign", sign);
                json.put("key", envelop);
            }
            return json;
        } catch (Exception e) {
            log.info("返回数据密失败");
            throw new Exception("返回数据密失败");
        }
    }

}

代码只用于理解加解密过程,如需要完整代码,可留言