支付宝 v3 验签如何实现

这篇具有很好参考价值的文章主要介绍了支付宝 v3 验签如何实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上次给大家介绍了 支付宝 v3 自签名如何实现 ,这次顺便再把验签也写一下。

 文章来源地址https://www.toymoban.com/news/detail-760660.html

为什么要验签

说起为什么要验签,如果要详细一点解释的话,可以写很多很多......

我们就简单一点来解释:验签可以证明接收到的信息是支付宝给我的,不是被人中途拦截篡改数据之后再发给我的。

 

支付宝的通知分为 「同步通知 」和 「异步通知 」:

  • 「同步通知 」就是我们请求支付宝之后,支付宝返回的数据。
  • 「异步通知 」是到达某些条件之后,支付宝主动发的;更详细内容可以参考之前我写的 [手把手|支付宝异步通知如何使用]。

 

对于这两种通知我们都需要进行验签处理,才能保证数据的准确性!(⚠️ 很重要!!)

 

其实支付宝给的 SDK 里面也封装了验签的方法,并且对同步通知都经过了验签的处理,同步验签不过的话,接口会直接抛出异常 [sign check fail: check Sign and Data Fail]。

另外 v3 SDK 里面提供的验签方法名跟 v2 版本是一样的,大家不想麻烦的话可以直接查看 [SDK如何实现验签]。

(大家凑合看,v3 版本好像还没有完整的验签示例代码,也可能是我没找到 😢

 

虽然给了这么多简单的方法,但是我就是要自!己!写!一!遍!╭(╯^╰)╮

 

如何验签

验签的流程比加签要简单一点,下面用支付宝同步通知的数据做验签例子

 

步骤一、接收支付宝返回的信息

首先就是要接收到支付宝返回的信息,因为是同步验签的数据,直接拿之前自签名的代码改一下

验签我们所需要的数据有:

  • aliapy-signature:支付宝生成的签名内容。
  • alipay-timestamp:支付宝应答时间戳。
  • alipay-nonce:支付宝应答随机串。
  • httpResponseBody:响应报文内容,自签名的 resData 数据。

接收代码

//获取响应的请求头head
Header[] responseHeader = response.getAllHeaders();
//待验签数据head:aliapy-signature、alipay-timestamp、alipay-nonce
String alipaysignature = response.getFirstHeader("alipay-signature").getValue();
String alipaytimestamp = response.getFirstHeader("alipay-timestamp").getValue();
String alipaynonce = response.getFirstHeader("alipay-nonce").getValue();    

 

获取到的响应值

httpResponseBody:{"out_trade_no":"20181128763521373251698","qr_code":"https://qr.alipay.com/bax04870evi3w2dlaeai2502"}
aliapy-signature:M/6yx2OajiQD0mM9Tk9ShsduFERtmj+xI0BN8QiZk8BMUCvMQCne1n/VIbMZ738k4No8nsE1DC0saPe2NqtmgxC3B+TmWgrhJ+4JOVEc7K4/LcIDWN2PaPCw5g5+oUQRIGCbo0+f9yqSew4NwETV2RiVIw91q+kJ4OeIpauSnGQAuwOxqciDM52k7gUhij8G+evhK7xn6TNhiQgRk0RjkyhEEp/00lYb5xI2d9Oj5KgsDC9KTRo9SO0SJaH0SbfNHU40XUkkomuj6jiOEeccfB6Fofzq5jfL3u24Ev9SxTDf2kYZzffShLrYhlrI8947VqC3h8/F6O8y4K/PQl3LCw==
alipay-timestamp:1703576825544
alipay-nonce:73b3422127c9996ad405e77091eef6f4

 

 

包含之前自签名的完整代码(仅供参考)

public class V3HttpPostTest {

    public static void main(String args[]) throws Exception {
        // 发送请求的url
        String url = "https://openapi.alipay.com/v3/alipay/trade/precreate";

        // 发送请求的内容
        String content = "{\"out_trade_no\":\"20181128763521373251698\",\"total_amount\":\"1\",\"subject\":\"123\",\"body\":\"body\"}";
        String chearset = "utf-8";
        // 创建请求对象:post或者get
        HttpPost httpPost = new HttpPost(url);
        // httpClient实例化
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 设置类型
        // "application/x-www-form-urlencoded","application/json"、multipart/form-data、text/xml
        httpPost.setHeader("Content-Type", "application/json");
        // 调用方的requestId,用于定位一次请求,需要每次请求保持唯一。
        httpPost.setHeader("alipay-request-id", "32432432432423421");
        httpPost.setHeader("authorization",
                "ALIPAY-SHA256withRSA app_id=2021111111111122,timestamp=1702452177941,nonce=3246658768654544,sign=WDF6pS2qK/kEZnsJDMrhNmd/z82ClZ+VMohYxIUs3MZ2j0m+4reQtSBGa6mZyA5ffbIPPvZTRO+1DLEuuCvZRMQGK3okYSA/ASP7GEqfCDeKmkqzKV2kWrmftNfO+EiIiCnsiyJG4SQ9G7s0OtmCT6wVkphW9wgk7mfUoF5a+Wo3kzvEur3U+7ZfSgLa4HXQG2xE+z7BjmHG8j1qVoVa/3TR1lVBAqOwkodZ9cSPKceK2RxaPkk8gsFbofbuARl5xBqDwkS2caTQu27+DLXT/QJOHRHRw5VtH9v8B7nT+nrijFjktm6hD7aIHuPon6TtEgnbtWltRizEZldh+Fo1Eg==");
        // 支付宝根证书序列号,使用证书模式时,需要传递该值
        // httpPost.setHeader("alipay-root-cert-sn", "");

        // 组织数据
        StringEntity se = null;
        try {
            se = new StringEntity(content);
            // 设置编码格式
            se.setContentEncoding(chearset);
            // 设置数据类型
            se.setContentType("application/json");
            // post请求,将请求体填充进httpPost
            httpPost.setEntity(se);
            // 通过执行httpPost获取实例
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            String resData = EntityUtils.toString(entity);
            System.out.println("httpResponseBody:" + resData);

            //获取响应的请求头head
            Header[] responseHeader = response.getAllHeaders();
            //待验签数据head:aliapy-signature、alipay-timestamp、alipay-nonce
            String alipaysignature = response.getFirstHeader("alipay-signature").getValue();
            String alipaytimestamp = response.getFirstHeader("alipay-timestamp").getValue();
            String alipaynonce = response.getFirstHeader("alipay-nonce").getValue();    
            System.out.println("aliapy-signature:" + alipaysignature);
            System.out.println("alipay-timestamp:" + alipaytimestamp);
            System.out.println("alipay-nonce:" + alipaynonce);
            
            // 关闭httpClient资源
            httpClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

 

 

步骤二、拼接待验签内容

接收到响应数据之后,我们需要按照

${alipay-timestamp}\n
${alipay-nonce}\n
${httpResponseBody}\n

规则,将数据组装起来。

 

content 组装示例

【注意:\n 不要丢!】

String content = alipaytimestamp + "\n" + alipaynonce + "\n" + httpResponseBody + "\n";

返回值

1703576825544
73b3422127c9996ad405e77091eef6f4
{"out_trade_no":"20181128763521373251698","qr_code":"https://qr.alipay.com/bax08770vkyzjc0is6ep25ed"}

 

步骤三、进行签名比对

组装完待验签内容之后,我们就可以将数据进行验签了,其中用到的参数有:

  • content:上一步获取到的内容。
  • alipaysignature:第一步获取到的 alipaysignature。
  • publicKey:为支付宝公钥,在支付宝平台上传应用公钥后获取,参考 [如何获取支付宝公钥]。
  • charset:编码格式,代码中用的是 UTF-8。

验签代码

private static boolean doVerify(String content, String alipaysignature, String publicKey, String charset) throws Exception {
        try {
            byte[] encodedKey = publicKey.getBytes();
            encodedKey = Base64.getDecoder().decode(encodedKey);
            PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encodedKey));

            java.security.Signature signature = java.security.Signature.getInstance("SHA256withRSA");
            signature.initVerify(pubKey);
            signature.update(content.getBytes(charset));
            

            boolean signVerified = signature.verify(Base64.getDecoder().decode(alipaysignature.getBytes()))
            System.out.println("signVerified:" + signVerified);
            return falg;

        } catch (Exception e) {
            String errorMessage = "验签失败,请检查公钥格式是否正确。content=" + content + " publicKey=" + publicKey + " reason="
                    + e.getMessage();
            throw new Exception(errorMessage);
        }

    }

返回值

signVerified:true

只有返回 true 才能说明验签是通过的。

 

写在最后

v3 验签写完之后,可以看到其实跟 v2 的验签方法没有什么区别,最大的不同点在于待验签内容,大家都可以试试看,还是挺简单的。

 

到了这里,关于支付宝 v3 验签如何实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java实现微信小程序V3支付

    2024年02月12日
    浏览(61)
  • PHP实现小程序微信支付(v3版本)

    PS:本篇文章是PHP对小程序进行微信支付v3版本的实现,仅用于对支付流程的了解,具体使用方面需要大家自行调整 小程序端JS代码: PHP类的相关代码:

    2024年02月12日
    浏览(53)
  • Java实现微信小程序V3支付 (完整demo)

    2024年02月07日
    浏览(40)
  • springboot实现微信小程序V3微信支付功能

    appId:小程序appid appSecret:小程序的secret mchId:商户号 keyPath:商户私钥路径(apiclient_key.pem) certPath:证书路径(apiclient_cert.pem) platFormPath:平台证书(cert.pem) 注 : 需要通过写程序生成平台证书(见v3Get()方法) apiKey3:apiv3密钥 serialnumber:商户证书序列号 notifyUrl:回调地

    2024年02月12日
    浏览(61)
  • PHP实现对微信支付v3版本回调数据的解密

    PS:本文使用了微信官方给出的demo来实现对回调数据的解密,本文主要对微信官方给出的demo如何使用作出部分个人讲解,以及对解密前后数据的格式进行展示 PHP类:这是微信官方给出的demo

    2024年02月15日
    浏览(48)
  • springboot整合IJPay实现微信支付-V3---微信小程序

    微信支付适用于许多场合,如小程序、网页支付、但微信支付相对于其他支付方式略显麻烦,我们使用IJpay框架进行整合 JPay 让支付触手可及, 封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。不依赖任何第三方 mvc 框架,仅仅作为工具使用简单

    2024年02月02日
    浏览(70)
  • 对接银行支付API,自己的demo可以调通,放到项目里,却总提示验签失败。原来竟是因为...

    对接一个银行支付通道的支付API,自己java写的demo可以调通,放到项目工程里,部署到环境上,总是收到验签失败的响应。这个问题,困扰我们的开发大兄弟长达一个星期。 对接通道接口联调不通,常见的场景有许多,如: 签名原串需要对key进行排序。不同的排序算法会导致

    2024年04月28日
    浏览(33)
  • SpringBoot整合微信小程序支付V3(支付、退款)

    微信支付开发前,需要先获取商家信息,包括商户号、AppId、证书和密钥。 获取商户号 微信商户平台 申请成为商户 = 提交资料 = 签署协议 = 获取商户号 获取AppID 微信公众平台 注册服务号 = 服务号认证 = 获取APPID = 绑定商户号 申请商户证书 登录商户平台 = 选择 账户中心 = 安

    2024年02月08日
    浏览(44)
  • 【微信支付】java-微信小程序支付-V3接口

    最开始需要在微信支付的官网注册一个商户; 在管理页面中申请关联小程序,通过小程序的 appid 进行关联;商户号和appid之间是多对多的关系 进入微信公众平台,功能-微信支付中确认关联 具体流程请浏览官方文档:接入前准备-小程序支付 | 微信支付商户平台文档中心 流程走

    2024年02月06日
    浏览(57)
  • 微信支付 API v3

    1. 获取商户API证书 登录商户平台【API安全】-【API证书】-【查看证书】,可查看商户API证书序列号。 商户API证书和微信支付平台证书均可以使用第三方的证书解析工具,查看证书内容。或者使用openssl命令行工具查看证书序列号。 2. 调用支付API生成签名生成 商户可以按照下述

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包