验证苹果支付付款令牌签名

问题描述 投票:0回答:1

出于某些原因,我必须在没有支付平台的情况下处理苹果支付支付令牌。根据official document,我需要首先“ 验证签名”。该签名是采用base64编码的独立PKCS#7签名。我想用node.js或openssl进行验证。

因为node-forge是一种非常方便的加密工具,目前尚不支持“带有sha256的ECDSA”(link),我找不到其他替代品。我转向openssl。经过调查,似乎签名以“ CMS签名数据”格式打包。因此,我发现openssl手册中的此命令应该可以完成此工作:

openssl cms -verify -inform DER -in signature.der -content content.txt

Apple文档说:“ 确保签名是ephemeralPublicKey,data,transactionId和applicationData密钥的串联值的有效ECDSA签名”。因此,我通过从我的测试令牌中隐藏这些字段来生成我的测试内容。但是结果是:

Verification failure
C0:25:34:08:01:00:00:00:error:CMS routines:CMS_SignerInfo_verify_content:verification failure:crypto/cms/cms_sd.c:901:
C0:25:34:08:01:00:00:00:error:CMS routines:CMS_verify:content verify error:crypto/cms/cms_smime.c:399:

cms_sd.c:901正在验证签名者,因此我认为此命令是我所需要的。那我做错了吗?

更新:我发现PKI.js可以完成这项工作。详细答案如下。

node.js openssl applepay
1个回答
0
投票

PKI.js example下面的代码片段显示了如何解析现有的CMSSignedData。

const testData = "<TOKEN_SIGNATURE>";

const cmsSignedBuffer = stringToArrayBuffer(fromBase64(testData));
const asn1 = asn1js.fromBER(cmsSignedBuffer);
const cmsContentSimpl = new ContentInfo({ schema: asn1.result });
const cmsSignedSimpl = new SignedData({ schema: cmsContentSimpl.content });

此后,我们可以提取证书和签名者信息以进行进一步处理。

检查OID]:

cmsSignedSimpl.certificates[0].extensions.find(x => x.extnID === '1.2.840.113635.100.6.29') // leaf certificate
cmsSignedSimpl.certificates[1].extensions.find(x => x.extnID === '1.2.840.113635.100.6.2.14') // intermediate certificate

验证签名和信任链

cmsSignedSimpl.verify({
    signer: 0,
    trustedCerts: [AppleRootCA_G3],
    data: signedData,
    checkChain: true, // check x509 chain of trust
    extendedMode: true, // enable to show signature validation result
  });

检查演唱时间

const attrs = cmsSignedSimpl.signerInfos[0].signedAttrs.attributes;
const signingTimeAttr = attrs.find(x => x.type === '1.2.840.113549.1.9.5');
const signingTime = new Date(signingTimeAttr.value[0].toDate());
© www.soinside.com 2019 - 2024. All rights reserved.