ESP32-C3通过ArduinoIDE实现支付宝签名算法RSA2(SHA256withRSA)

代签当面付请找我0.38.Q7728775181
请在开发的应用中调用当面付的话写上我的推荐人PID参数,这样我才能收到一点点手续费分成。你想想总共才付千分之4刨去他们的运营成本我还能有多少?
重点来了
务必把
sys_service_provider_id设置成2088931278114101我才能拿到回扣

正片开始

支付宝当面付门店直连的问题解决
在这里插入图片描述
https://opendocs.alipay.com/open/194/106039?pathHash=5b8cf9e6
支付宝说了一种收银机直连后台的方案,但问题是当面付SDK却只有PHP/JSP/ASP这几种当然还有一种C调用CRUL的,这些SDK都有一个共同的特点就是大,不能用于如ESP32的IOT设备,于是我想自行实现API
,API的算法如下
今年支付宝将停用所有除RSA2(2048)以外的算法,特别是古老的MD5算法网关,SHA1算法网关新客户也不能签约了,只剩下RSA2(2048以上)
而且推荐使用证书方式

1 拼接所有参数并按字母排序(a-z)
2签名使用 RSA2(SHA256withRSA)并将签名附在最后&sign=xxxxxx
3拼接所有参数后通过POST或GET方式(任选其一可以混发)向网关发送请求

但值得注意的是所有参数需合并到一起去计算签名,浏览器抓包不要忘记将POST和GET参数合并
根据支付宝自签名指南https://opendocs.alipay.com/common/057k53?pathHash=7b14a0af和相关工具 支付宝开放平台密钥工具进行签名调试

值得注意的是证书序列号的计算,由于需要提取SN在单片机上提取证书签发机关及各项内容并计算MD5比较麻烦,推荐用别的语言(PHP ASP JSP)在本地环境下通过调用官方SDK并下断点取得各证书的SN
主要牵扯到的是alipay_root_cert_sn和app_cert_sn也可以运行DMEO浏览器抓包获得

以下是我抓到的待签名字符串

alipay_root_cert_sn=687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6&alipay_sdk=alipay-sdk-php-2020-04-15&app_cert_sn=0fbfea6f1c396ed1ee67302f2d035201&app_id=2021001194613478&biz_content=%7B%22out_trade_no%22%3A%22wlwt20230605114453%22%2C%22total_amount%22%3A0.01%2C%22subject%22%3A%22%5Cu5f53%5Cu9762%5Cu4ed8%5Cu6d4b%5Cu8bd5%22%7D&charset=UTF-8&format=json&method=alipay.trade.precreate&notify_url=https%3A%2F%2Fwww.mizhikeji.com%2Falipaynotify%2F&sign_type=RSA2&timestamp=2023-06-05+14%3A09%3A31&version=1.0

在待签名字符串末尾增加参数&sign=xxxxxxxxxx就可以向网关进行发包了```

在阿里提供的工具或其他在线RSA2签名网站即可测试签名算法(如http://www.metools.info/code/c82.html)上即可在线签名测试但尤其注意的是阿里提供的工具需要将-----BEGIN RSA PRIVATE KEY----- 和-----END RSA PRIVATE KEY----- 删除并把所有的密钥写在同一行
需要注意的是谨防密钥失窃
1主机提供商坚守自盗2黑客攻击窃取3不明算法调试网站自行上传

下述代码即可在Arduino平台上实现对任意字符串的SHA256withRSA签名
具体计算流程分为3步
第一步 计算字符串的SHA256摘要
第二步 使用RSA算法对字符串摘要进行签名
第三步 将签名转化成base64格式
这里我使用的是库中的mbedtls_pk_sign()
这个算法应该是可以根据参数进行不同的加密计算
应该还有一个算法mbedtls_rsa_rsassa_pkcs1_v15_sign(rsa, mbedtls_ctr_drbg_random, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_NONE, hashlen, hash, sign)
这个算法钻研了很久未能调通,但既然功能一样那索性就当同一个算法得了。值得注意的RSA签名算法有很多种这里应该采用的是v1.5版本

环境安装参考https://blog.csdn.net/imba_wolf/article/details/122417540的教程
加密库地址https://johanneskinzig.de/index.php/files/26/Arduino-mbedtls/9/gettingstartedmbedtlsarduino.7z
及Arduino IDE拓展库base64_encode
这里计算的是 const char *data = “a=1”;
也就是计算字符串“a=1”的签名值

//作者QQ772875181 支付宝SHA256withRSA签名的Arduino实现
#include <mbedtls/pk.h>
#include <mbedtls/rsa.h>
#include <mbedtls/pem.h>
#include <mbedtls/sha256.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>//环境安装参考https://blog.csdn.net/imba_wolf/article/details/122417540的教程
#include <arduino_base64.hpp>//https://github.com/dojyorin/arduino_base64 随便拉的库 库管理搜base64_encode作者dojyorin
void setup() {
  Serial.begin(115200);

  mbedtls_pk_context key;
  mbedtls_rsa_context *rsa = NULL;
  mbedtls_ctr_drbg_context ctr_drbg;

  mbedtls_pk_init(&key);
  mbedtls_ctr_drbg_init(&ctr_drbg);

  // 初始化随机数生成器
  const char *personalization = "random_seed";
  mbedtls_entropy_context entropy;
  mbedtls_entropy_init(&entropy);
  mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)personalization, strlen(personalization));

  // 解析PEM格式的密钥字符串
  const char *pemKey = R"(
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuRxgd36cFdmebg79B6heLLsmvtLbUeLiGbn7RQ2B8D7nBqXP
0e0Kipf/VfA3Q1cDuz+YbauG+1RE+czXCfy4/ErGcmWP8dTwdzLIkfM2bcbNVamG
Fi95KFhd7kYNDLpCv1eVpJWShV3F9LsBjvdQ4E1NqG9wHq1aVX1gQjw4v4LPHlEr
1HHYL1bRuWE+66msw3PhGMZbk2TgSO9ecwsuWj1RB85CdOfxn2k4CKYrWAfBy+Lu
DvZ1qYScyCe5+C8aqQRBbxAY5ITukftkSSgNNAW9851bATKg0tr7h7r9eP/jiyk/
346q3zxFnXJpZSZBZT6KulYbU5cz1ZZE8VduRQIDAQABAoIBAFLvBcFDtkaL01FX
4cF2i4ra5ocEDULotYf1LUBIxviOFg+CZlOVMe3aH4mvL/M5nvBbk70+5iDgJm8M
eSN+WJqgHbzPB+i/EGU3GWlaX/5a3VANvYdfCZcr0BmaxOn44UK8yMyOPrEFzFTT
G+WjpFZ6C9r04nS8EgbPPzsto/cYrvJ/eACaqsy4w9EpYXJdvX3iV42m+yyYQzaW
jLYz/iLiO2XYCJE7gV9OLxxWCbXvooIOLc9P+d7jtav1LDw1aiflQ1Van+ajqLGO
NgnQcow8qa2lOK49ygoX4ChoLCbjZsRH/LT64ibZlwczcf/9s0RCkmxNcnPZ60Rz
CFqwrIECgYEA4AduMcfzaCrFA6HLAHGDGGkqLbh9bmB0MfMKMxFhZaSyn/iZhcUP
XxjdK5PfzE4utDE5RV+HlqwbDVgVgTpi0/FV4Bxa+yWT+ltrB4vOrDVQyC82hMWK
F87OL+cFzWHFvLd/FVaMPumeTefMa917T1mlsH026oJwliQlL9X2vlECgYEA04cg
0r55AJSApFABFA3NF2qO/BulbOFNfC2HiUIqOcih82iPjElq3iUcM2yoDAlCvOxr
06NnMDBVYVX+p7OeFMPbjM6Mi62lpa500IZCg+GlO21l7WCWPabmSo2Kg27I5ejl
owmP87rst2kcbs8TsvTuAuU4c3ghD6Td3jdSL7UCgYBmdH983MkA1q6LXq8MYN1n
iJD1n+4dUJdTUKdVe5ljdtMKPhNYDitdfm2HxHURZqANYIWkqG/GBKfKjoInO6B+
9VwkxlMFkMYANVbZeKLoNune41i3l+/zu2yok6sfpptcFz9TbuVs0ELJtjzTB9Oh
EoqoEFvRHB6JS7aGDgBuQQKBgDh/0muYBrf58nZxDCiwGwTTKIf8Vm5Dq6+sdZRb
AO5YQbHDTvxYq9vUK7ksn6I/Yv0VZSOtdKVxc4zBLHjcyC+htOXiUbYJVsJvW7JK
+j9BqSG7ccs6zkZ/aumk7sd2cuC+GYA30KR4XDwNLlQGqatWMrDBSxfEkYgdMEnn
muM1AoGBAMgafcagqkjYSOJvtZ+SAEMni1zrASLUKwVo9lmRz110gEmROicGcvV/
oHKdCdTsXi5oDQyFlqRlvN+yCbFRkRvCFlO03tkwU4yb2AKNPNf9UDoqB3q6etzc
y3/b5CSBY7YXdOtPeZovXvDafk/bhJa2a3Vh/XUn96tPSHkNMa5w
-----END RSA PRIVATE KEY-----

)";

  int ret = mbedtls_pk_parse_key(&key, (const unsigned char *)pemKey, strlen(pemKey) + 1, NULL, 0);
  if (ret != 0) {
    Serial.println("Failed to parse private key.");
    Serial.println(ret);
    while (1) {}//程序死锁防止跑飞
  }

  // 计算SHA256哈希值
  const char *data = "a=1";
  unsigned char hash[32];
  mbedtls_sha256((const unsigned char *)data, strlen(data), hash, 0);
  // for (size_t i = 0; i <32; i++) {
  //   Serial.print(hash[i], HEX);//输出SHA256
  // }
  // 使用密钥对哈希值进行数字签名
  unsigned char signature[256];
  size_t signatureLen;
  ret = mbedtls_pk_sign(&key, MBEDTLS_MD_SHA256, hash, sizeof(hash), signature, &signatureLen, mbedtls_ctr_drbg_random, &ctr_drbg);
  if (ret != 0) {
    Serial.println("Failed to sign the data.");
    Serial.println(ret);
    while (1) {}
  }

  // 打印签名结果

  char hexString[5];
  // Serial.print("SignatureIS: ");
  // for (size_t i = 0; i < signatureLen; i++) {
  //   // Serial.print(signature[i], HEX);
  //   sprintf(hexString, "%02X", signature[i]);
  //   Serial.print(hexString);//输出SHA256withRSA的16进制结果
  // }

  char base64signoutput[base64::encodeLength(sizeof(signature))];//制造一个长度仅为base生成长度一致的字符串
  base64::encode(signature,sizeof(signature), base64signoutput);
  Serial.println("SHA256withRSAsignIS:");
  Serial.println(base64signoutput);

  // 清理资源
  mbedtls_pk_free(&key);
  mbedtls_ctr_drbg_free(&ctr_drbg);
  mbedtls_entropy_free(&entropy);

  // 签名完成后的处理...

  // delay(1000);
}

void loop() {
}

最终输出运行结果与支付宝签名工具给出的结果一致
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
国际算法SHA256withRSA是一种基于SHA256哈希算法RSA非对称加密算法的数字签名算法。它使用SHA256对待签名的数据进行哈希计算,然后使用RSA算法对哈希值进行加密。这种算法通常用于数据的加密和数字签名验证,可以确保数据的完整性和身份的真实性。通过私钥对数据进行签名,然后使用公钥进行验签,可以确保数据在传输过程中没有被篡改,并且确保数据的发送方身份的真实性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java SHA256withRSA,json数据证书加签验签](https://download.csdn.net/download/sunny_lv/12786779)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [签名算法sha256withrsaRSA数字证书公钥私钥生成,base64转码和文件日志](https://blog.csdn.net/qq_41912505/article/details/107640004)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [PHP MD5withRSA、SHA1withRSASHA256withRSA算法签名](https://blog.csdn.net/xiayu204575/article/details/106589772)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值