首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Apple如何从支付令牌中比较商家公钥和publicKeyHash?

Apple如何从支付令牌中比较商家公钥和publicKeyHash?
EN

Stack Overflow用户
提问于 2017-07-11 16:37:45
回答 4查看 4.3K关注 0票数 1

我正在研究苹果支付令牌解密。根据这条指示,支付令牌格式参考在第二步。我需要使用publicKeyHash字段从头支付令牌,以确定哪个商家的证书被苹果使用。

pulbicKeyHash是商人证书的X.509编码公钥字节的SHA-256散列,Base64编码为字符串。

我有一张商人证书。因此,我假设,如果我使用我的证书的公钥的sha-256散列并对其进行Base64编码,我将得到与在支付令牌的publicKeyHash字段中接收到的值相同的值。

但我不知道证书的哪一部分应该散列。苹果公司提供的初始商户证书采用.cer格式。我已经从它中提取了公钥到.pem格式。这两种方法都是哈希-> base64encode of公共密钥(在-开始证书-和-开始证书-开始证书-字符串在-开始证书

两家公司都未能与从苹果支付( Apple Pay )获得的价值相匹配。而且它有不同的长度,我的base64编码散列有88个字符长度,publicKeyHash字段的长度是44个字符。

当我试图将64位解码publicKeyHash时,我有一些不可读的字符,比如"D�đ���$�f���@c���$����WP��“,但根据苹果的文档,应该有沙-256散列,不能包含这样的符号。

有人能解释一下我应该执行什么具体步骤来完成这个商户证书的检查吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-08-16 14:38:26

在我的例子中,主要的问题和解决方案是使用支付处理证书的公钥哈希,以及NOT 的公钥哈希,即我试图从支付令牌中与PublicKeyHash进行比较。在我的借口中,我可以说,苹果文档的以下文本非常模糊:

publicKeyHash SHA-256散列,Base64编码为商人证书的X.509编码公钥字节的字符串哈希。

由于我们有两种证商和付款处理。很明显,从文档中获得的商人证书就是商人身份证书。

只在重新阅读付款处理证书说明之后

付款处理证书。用于安全传输支付数据的证书。Apple服务器使用支付处理证书的公钥对支付数据进行加密。在处理付款时使用私钥解密数据。

Apple Pay JS文档中,我意识到了我的错误。

因此,我希望我的经验能帮助别人不要踩到同样的耙)

票数 4
EN

Stack Overflow用户

发布于 2018-12-02 01:39:10

遗憾的是,我未能找到openssl命令直接从证书中提取散列。因此,您必须首先创建公钥,以获得公钥哈希。提取公钥的方法有两种。

步骤1

从您的ecc私钥(支付处理私钥)

代码语言:javascript
复制
openssl ec -in ecc_private_key.key -pubout -out ec_public_key.pem

B.从apple pay门户下载的证书(上传支付处理后的csr)

代码语言:javascript
复制
openssl x509 -inform der -in apple_pay.cer -pubkey -noout > apple_pay_public_key.pem

两者都将以下列格式提供公钥

代码语言:javascript
复制
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENGbyXUzeZTdeyyNuXyc0nMzXmnLl
xMwd/t/sCZr3RPhytPbZpR/V4/xHqN/MVzozzq30I0/eUefbThEBl236Og==
-----END PUBLIC KEY-----

步骤2

您可以使用下面的代码从上面的公钥中提取base64哈希,记住要删除标头/页脚和行提要。

我希望我能弄清楚如何使用openssl工具从公钥中获取散列,但无论如何,遵循c#代码对我是有用的。它非常简单,很容易移植到java/python/php或任何您喜欢的地方。或者只需在ideone.com在线使用下面的代码

代码语言:javascript
复制
String publicKeyBase64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENGbyXUzeZTdeyyNuXyc0nMzXmnLlxMwd/t/sCZr3RPhytPbZpR/V4/xHqN/MVzozzq30I0/eUefbThEBl236Og==";

byte[] publicKey = Convert.FromBase64String(publicKeyBase64);
SHA256 sha256 = SHA256Managed.Create();
byte[] hash = sha256.ComputeHash(publicKey);
String publicKeyHash = Convert.ToBase64String(hash);

Console.WriteLine("Result: {0}", publicKeyHash);

请记住,您的系统应该能够在任何给定的时间接受多个密钥,而不是仅仅验证您需要根据从设备(iphone/ipad等)接收到的publicKeyHash加载正确的私钥,考虑到当前证书过期(或由于任何原因而被撤销)的情况,否则您的系统可能无法在短时间内接受事务。据我的一次遭遇,苹果花了一个多小时,然后新的支付处理密钥变得活跃,之后按下激活在门户。

票数 4
EN

Stack Overflow用户

发布于 2017-10-26 19:09:33

这个问题和公认的答案在细节上仍然有点模糊,因此这里是在java中验证token.paymentData.header.publicKeyHash是否与苹果支付处理证书匹配的确切测试方法:

代码语言:javascript
复制
private static void checkPublicKeyHash(String publicKeyHash, X509Certificate paymentProcessingCertificate)
        throws NoSuchAlgorithmException, CertificateException {

    String certHash = Base64.getEncoder().encodeToString(
            MessageDigest.getInstance("SHA-256").digest(
                    paymentProcessingCertificate.getPublicKey().getEncoded()));
    if (!Objects.equals(publicKeyHash, certHash)) {
        throw new DigestException(String.format(
                "publicKeyHash %s doesn't match Payment Processing Certificate hash %s",
                publicKeyHash, certHash));
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45040171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档