java-非对称(RSA)签名加密(springboot框架)

1. 请求地址
2.请求参数
参数类型是否必填最大长度描述示例值
out_biz_noString必选订单号201806300001
amountPrice必选20订单总金额,单位为分,不支持千位分隔符,精确到小数点后两位,取值范围[10,1000000000]。23.00
identityString必选64支付宝账号 :用于登录支付宝的账号111111
nameString必选用户姓名张三
signTypeString必选签名类型 RSA MD5 建议使用MD5201905代发
signString必选签名

3.响应参数

参数类型是否必填最大长度描述示例值
codeString-网关返回码,详见文档40004
msgString-网关返回码描述,详见文档Business Failed
sub_codeString-业务返回码,参见具体的API接口文档ACQ.TRADE_HAS_SUCCESS
sub_msgString-业务返回码描述,参见具体的API接口文档交易已被支付
out_biz_noString商户订单号
order_idString支付宝转账订单号
pay_fund_order_idString支付宝支付资金流水号
status状态
trans_dateString订单支付时间

签名:

使用RSA 签名, java 代码示例:


package com.chimera.boomshop.utils;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wiremock.org.apache.commons.lang3.ArrayUtils;
import wiremock.org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;

public class SignUtil {
    static Logger log = LoggerFactory.getLogger(SignUtil.class);
    private static final String SIGN_TYPE_RSA = "RSA";
    public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";

    /**
     * 创建签名
     *
     * @param bean
     * @param signKey
     * @return
     */
    public static String createSign(Object bean, String signKey) {
        return createSign(bean2Map(bean), SIGN_TYPE_RSA, signKey);
    }


    /**
     * 创建签名
     *
     * @param params
     * @param signType MD5  和  RSA
     * @param signKey
     * @return
     */
    public static String createSign(Map<String, String> params, String signType, String signKey) {
        return createSign(params, signType, signKey, new String[]{"sign"});
    }

    public static String createSign(Map<String, String> params, String signType, String signKey, String[] ignoredParams) {
        String signStr = getSignString(params, signKey, signType, ignoredParams);
        log.debug("签名前STR={}", signStr);
        if (Objects.equals(SIGN_TYPE_RSA, signType)) {
            // 使用RSA 签名
            signStr = signRSA(signStr, signKey);
        } else {
            signStr = DigestUtils.md5Hex(signStr).toUpperCase();
        }
        log.debug("签名后STR={}", signStr);
        return signStr;
    }

    private static String getSignString(Map<String, String> params, String signType, String signKey, String[] ignoredParams) {
        StringBuilder toSign = new StringBuilder();
        for (String key : new TreeMap<>(params).keySet()) {
            String value = params.get(key);
            boolean shouldSign = false;
            if (StringUtils.isNotEmpty(value) && !ArrayUtils.contains(ignoredParams, key)) {
                shouldSign = true;
            }
            if (shouldSign) {
                toSign.append(key).append("=").append(value).append("&");
            }
        }
        if (Objects.equals(SIGN_TYPE_RSA, signType)) {
            toSign.append("key=").append(signType);
        } else {
            toSign.append("key=").append(signKey);
        }
        return toSign.toString();
    }

    private static String signRSA(String data, String signKey) {
        String signature = null;
        try {
            PrivateKey privateKey = getPrivateKey(signKey);
            Signature Sign = Signature.getInstance(SIGNATURE_ALGORITHM);
            Sign.initSign(privateKey);
            Sign.update(data.getBytes());
            signature = Base64.encodeBase64String(Sign.sign());

        } catch (Exception e) {
            log.error("签名失败! msg:{}", e.getMessage(), e);
        }
        return signature;
    }

    private static PrivateKey getPrivateKey(String signKey) throws InvalidKeySpecException, NoSuchAlgorithmException {
        KeyFactory keyFactory = KeyFactory.getInstance(SIGN_TYPE_RSA);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(signKey)));
    }

    /**
     * Bean 转 Map
     *
     * @param bean
     * @return
     */
    private static Map<String, String> bean2Map(Object bean) {
        Map<String, String> result = new HashMap<>();
        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            try {
                boolean isAccessible = field.isAccessible();
                field.setAccessible(true);
                if (field.get(bean) == null) {
                    field.setAccessible(isAccessible);
                    continue;
                }
                //忽略掉静态成员变量
                if (!Modifier.isStatic(field.getModifiers())) {
                    result.put(field.getName(), field.get(bean).toString());
                }
                field.setAccessible(isAccessible);
            } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
                log.error(e.getMessage(), e);
            }
        }
        return result;
    }

    /**
     * 签名
     *
     * @param bean
     * @param signature
     * @return
     */
    public static boolean checkSign(Object bean, String signature) {
        Map<String, String> params = bean2Map(bean);

        if (Objects.equals(SIGN_TYPE_RSA, params.get("signType"))) {
            return verifySign(params, signature, params.get("sign"));
        }
        String sign = createSign(params, signature);
        return sign.equals(params.get("sign"));
    }

    private static boolean verifySign(Map<String, String> params, String publicKey, String signature) {
        String signString = getSignString(params, SIGN_TYPE_RSA, null, new String[]{"sign"});
        return verifySignRSA(signString, publicKey, signature);
    }

    private static boolean verifySignRSA(String data, String publicKeyStr, String signature) {
        boolean verifySignSuccess = false;
        try {
            PublicKey publicKey = getPublicKey(publicKeyStr);
            Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM);
            verifySign.initVerify(publicKey);
            verifySign.update(data.getBytes());
            verifySignSuccess = verifySign.verify(Base64.decodeBase64(signature));
        } catch (Exception e) {
            log.error("签名失败! msg:{}", e.getMessage(), e);
        }
        return verifySignSuccess;

    }

    private static PublicKey getPublicKey(String signKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory keyFactory = KeyFactory.getInstance(SIGN_TYPE_RSA);
        return keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(signKey)));
    }

}



调用示例:

 TransferReq req = new TransferReq();
        req.setName("AA");
        req.setAmount(10);
        req.setIdentity("XT0001");
        req.setOutBizOrder("XT0001");
        req.setSignType("RSA");
      String signValue = SignUtil.createSign(req, privateKey);
	reqreq.setSign(signValue);

HttpCli.post(req);

privateKey 加解密私钥

MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClNwjR0If7x3O9fWqmO7Y0g1FpRxq+QDnInRPWiNvkrkJ6fBasPr5Ea9NVcI8i0KVrBaaX9v4aP8pYuqmzw4tTyLNLLD9zJyrTFkIYyj2+XBQpUBwgc8FU9LwsfI05v6LjkU0OmJ/idJHTbOwdowoyxfw6npfqU6k7kF5sc2Tbrs0oYnJYyaFhGIsC74K/wCWlXX9RD3TnPo45zBo3k0I9HmbUEb4c4RfU8qZVVYx02Vd4Ytju857Sw5nzbd+svZD7lFpeFdt7Y8YlQlfxBb5ZeDjLN3zNNhOe9kXXs5r+FVZKi0iJVchBMp0YbJ3OXOZ0nFX/pu3lVnw8DvNjtooNAgMBAAECggEAfZDLSjOT9j7Lb1vvf3HodBbN/BaHc8r6X8dKOYYAodfzPIYs8TIqh3PvxYLrtoke/6zmxZ5511deIXuU2MQokz/5TIvPmWROPuouyAqFTLVMuW1iQyPW7wumLKVo7FgCo7Rd/VbwRTtVTXv+JDQy3w3sOl0olnaJK3T43rIBGJiTYEcZIJcVygNa/M+A0FeRrN8R4pTPTXz457qqaY8KHihzeZ3q9J6mSU5eOVsVAUa1jEDHhVGdl1CSt4G5GRGQ8Twsghl+Oqj/W23fMydNaJ4N10MfiTbKiB6X81vN336ned11h86y41UlUNdmANqyM2wxq9/LboHukAJ7+fjwgQKBgQDd2KGYh1ef3sG5Q9atDiFNbvG7hNDs+NZlWmwSXLqDmZzvPMMM7VlKFLp9Pync4hu3Co4FMFSK2ztZ7YqGD0R3jgz4YmOY1M8YI0rDfJvCfe8Fmdc0wy3f9tOswmQIL1Soo9tWbS71SH6II0GU44QsJt/KpGf+tEfrtTkZ8xPaYQKBgQC+pnYuIAod1Ul0zj2xZ1ctbOmkDqewQAscFjEHK46gsGScKMB5vI3EI9UXYcnbL7DxZiVbJyPpi3SGJdLRYUOTO6iLg+GVm9Z42fWCsnpGCH1sNynb3mUWJ96sFwDGzHKHxPR1zSoitnazdsvYL+zAYMrPvnlunKNI3XawaxCHLQKBgQDAaAp/R6LvvTs3e2bNYNvxVK/De0XYwVjxPqNMqa/6Q1ihBYoFxDUU0zWLOyULte9jqXvTdD9ezxWCwUrLSqKPLlyBcJQBEVEsFi/ZrFFLNf4AVZUY5c772A9uXopzrtk2CidJphh8FAvp9uoCP/F6eZzPHBg2CBX4kIydvP0TAQKBgH07SPvpbdvE45iHdPzYPeqH1T0/pyTeHK4ZYaEtGmYxGBV/q1cL5S+Gvg263WZOAHPBPh6PKkbZpPQNWlrRAhtvn7ntKjwk/o+p1FxCspDYONLhtWxIvKv+CoWOIqNzXnQSiuXqm5frtTMTgLkEWgbQTciCfK+M0rElUDZ4TYYNAoGAQvkGfZr9VbO9TIEXuUsdwyd7qg1azvL83cgo4aennub5S6AMqP8zO9xTnHWF3DVMp7ET6rdyD7vraCH/7Vm4vdwQiK1TCM2JEX46JyEaWPzgwEfDC4oC96jM+V/horQ9BorMnl9QNmF2xrU6mPiJ9+HT6ganW4JdvjE353BCfSE=

publicKey 加密/解密 公钥

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApTcI0dCH+8dzvX1qpju2NINRaUcavkA5yJ0T1ojb5K5CenwWrD6+RGvTVXCPItClawWml/b+Gj/KWLqps8OLU8izSyw/cycq0xZCGMo9vlwUKVAcIHPBVPS8LHyNOb+i45FNDpif4nSR02zsHaMKMsX8Op6X6lOpO5BebHNk267NKGJyWMmhYRiLAu+Cv8AlpV1/UQ905z6OOcwaN5NCPR5m1BG+HOEX1PKmVVWMdNlXeGLY7vOe0sOZ823frL2Q+5RaXhXbe2PGJUJX8QW+WXg4yzd8zTYTnvZF17Oa/hVWSotIiVXIQTKdGGydzlzmdJxV/6bt5VZ8PA7zY7aKDQIDAQAB
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值