【问题标题】:Validating apple pay payment token signature验证 Apple Pay 支付令牌签名
【发布时间】:2020-08-18 17:47:37
【问题描述】:

由于某些原因,我必须在没有支付平台的情况下处理 Apple Pay 支付令牌。根据official document,我需要先“验证签名”。并且签名是一个分离的 PKCS #7 签名,采用 base64 编码。我想用 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 是签名者验证 igest 所以我认为这个命令是我需要的。那我做错了什么?

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

【问题讨论】:

    标签: node.js openssl applepay


    【解决方案1】:

    PKI.js example 下面的代码 sn-p 显示了如何解析现有的 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());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-27
      • 2013-11-18
      • 2019-03-21
      • 2020-11-12
      • 1970-01-01
      • 2019-10-16
      相关资源
      最近更新 更多