You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript解密ApplePay Token?求等价OpenSSL调用及NPM包

移植Apple Pay Token解密:Ruby到JavaScript的等价实现

嘿,我来帮你把Ruby里的Apple Pay Token解密逻辑移植到JavaScript里!你提到的那些OpenSSL调用,用Node.js内置的crypto模块就能完全对应上,不用额外装第三方包(毕竟你在能获取NPM包的环境,Node.js是最适配的选择)。下面我一步步拆解对应关系和代码:

核心Ruby操作的JS等价映射

先把你给出的Ruby代码里的关键组件拆解清楚,再对应到JS的实现:

  • OpenSSL::Cipher.new("aes-256-gcm").decrypt:初始化AES-256-GCM解密器
  • OpenSSL::PKey::EC.new(Base64.decode64(ephemeral_public_key)):解析Base64编码的EC临时公钥
  • Digest::SHA256.new:SHA256哈希摘要生成
  • OpenSSL::X509::Store.new:X509证书链验证

1. AES-256-GCM解密器初始化

Ruby里的解密器初始化,对应Node.js crypto模块的createDecipheriv方法(注意GCM模式必须手动传入IV和认证标签,Ruby会隐式处理的部分JS需要显式声明):

const crypto = require('crypto');

// 假设你已经从Apple Pay Token中提取出了密钥、IV、认证标签
const decipher = crypto.createDecipheriv('aes-256-gcm', aesKey, ivBuffer);
decipher.setAuthTag(authTagBuffer); // GCM模式必须设置认证标签,否则解密会失败

2. 解析EC临时公钥

Ruby里解析Base64编码的EC公钥,对应Node.js的crypto.createPublicKey方法。Apple Pay的临时公钥一般是SPKI格式的DER编码Base64,所以直接按下面的方式解析:

const ephemeralPublicKeyBase64 = '从Payment Token里拿到的临时公钥Base64';
const publicKey = crypto.createPublicKey({
  key: Buffer.from(ephemeralPublicKeyBase64, 'base64'),
  format: 'der',
  type: 'spki'
});

3. SHA256摘要计算

Ruby的Digest::SHA256.new对应Node.js的crypto.createHash,用法非常直观:

const hash = crypto.createHash('sha256');
hash.update('需要计算哈希的内容'); // 可以传字符串或Buffer
const sha256Digest = hash.digest('hex'); // 输出十六进制格式,也可以用'base64'

4. X509证书存储与验证

Ruby的OpenSSL::X509::Store.new用于验证Apple Pay的证书链,在Node.js里可以用crypto.X509Certificate类来实现:

const fs = require('fs');
const crypto = require('crypto');

// 读取Apple官方的根CA证书(你需要提前下载好)
const appleRootCA = fs.readFileSync('apple_root_ca.pem');
// 解析从Payment Token里拿到的Apple Pay证书
const applePayCert = new crypto.X509Certificate(applePayCertBuffer);

// 验证证书链是否合法,验证通过返回true,失败则抛出错误
applePayCert.verify(appleRootCA);

完整解密流程补充

顺便给你补一下Apple Pay Token解密的完整核心步骤,对应Gala项目里的逻辑:

  1. 从Payment Token中提取临时公钥、加密的对称密钥、IV、认证标签、加密的支付数据
  2. 用你的商户EC私钥和临时公钥执行ECDH密钥交换,生成共享密钥:
    const merchantPrivateKey = crypto.createPrivateKey('你的商户EC私钥PEM/DER');
    const ecdh = crypto.createECDH('prime256v1'); // Apple Pay用的是P-256曲线
    ecdh.setPrivateKey(merchantPrivateKey);
    const sharedSecret = ecdh.computeSecret(publicKey);
    
  3. 对共享密钥做SHA256哈希,得到最终的AES解密密钥:
    const aesKey = crypto.createHash('sha256').update(sharedSecret).digest();
    
  4. 用前面初始化的AES-256-GCM解密器解密支付数据:
    let decrypted = decipher.update(encryptedPaymentData);
    decrypted = Buffer.concat([decrypted, decipher.final()]);
    

额外提示

如果是在浏览器环境下,你需要用Web Crypto API,但你说的是NPM环境,Node.js的crypto模块性能更好且更可靠,完全满足需求。如果需要更上层的封装,也可以考虑node-forge,但内置模块已经足够。

内容的提问来源于stack exchange,提问作者Matt Hudson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:32:16