RSA签名

RSA算法是一种非对称加密算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另外一才能解密。密钥分为公钥和私钥,私钥是自己保存,公钥提供给对方。
加密解密

  • 用公钥(他人)加密 私钥解密 mess–>公钥–>加密–>私钥–>解密 全密文
  • 需要时间,消耗性能,限制字数

签名验签

  • 用私钥(自己)签名公钥验签 mess–>私钥–>签名–>公钥–>验签 明文和签名

  • 使用私钥将明文进行签名生成密文串与明文一起传输。对方收到数据后使用公钥对明文和密文串进行验签。如果验通过就说明第一数据没有被修改过;第二这些数据一定是持有私钥的人发送的,因为私钥只有自己持有,这就起到防抵赖的作用

验签时机

  • 拦截器:拦截到调用方的请求然后进行验签 问题:我们的下单请求使用的是post
    如果在拦截器内要想获取到明文(请求参数)就必须要读取报文体,这是一个io流只能读取一次,如果我们在拦截器内读取了,在controller里我们就获取不到这个请求体了也就不能使用spring帮我们解析请求参数了
  • AOP

验签过程

  1. 调用方在请求头中传递authId、sign
  2. 使用AOP在执行实际方法前根据authId获取到公钥,进行验签
  3. 验签通过就继续执行

rsa密钥在线生成
在这里插入图片描述

工具类

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAUtil {
    static Logger LOG = LoggerFactory.getLogger(RSAUtil.class);

    private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";                     //签名算法
    private static final String KEY_ALGORITHM = "RSA";        //加密算法RSA

    /**
     * 公钥验签
     *
     * @param text      原字符串
     * @param sign      签名结果
     * @param publicKey 公钥
     * @return 验签结果
     */
    public static boolean verify(String text, String sign, String publicKey) {
        try {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            PublicKey key = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey)));
            signature.initVerify(key);
            signature.update(text.getBytes());
            return signature.verify(Base64.decodeBase64(sign));
        } catch (Exception e) {
            LOG.error("验签失败:text={},sign={}", text, sign, e);
        }
        return false;
    }

    /**
     * 签名字符串
     *
     * @param text       需要签名的字符串
     * @param privateKey 私钥(BASE64编码)
     * @return 签名结果(BASE64编码)
     */
    public static String sign(String text, String privateKey) {
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(privateK);
            signature.update(text.getBytes());
            byte[] result = signature.sign();
            return Base64.encodeBase64String(result);
        } catch (Exception e) {
            LOG.error("签名失败,text={}", text, e);
        }
        return null;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值