Apple Pay - 如何将商家公钥与来自付款令牌的publicKeyHash进行比较?

时间:2017-07-11 16:37:45

标签: encryption base64 sha256 applepay

我正在进行Apple Pay支付令牌解密。 根据步骤2中的这条指令Payment Token Format Reference,我需要使用支付令牌标题中的publicKeyHash字段来确定哪一个 商家证书被Apple使用。

pulbicKeyHash是商家证书的X.509编码公钥字节的SHA-256哈希值,Base64编码为字符串。

我有一张商家证书。所以我假设如果我将使用我的证书的公钥和Base64编码的sha-256哈希,我将获得与我在publicKeyHash支付令牌字段中收到的值相同的值。

但我无法弄清楚我应该散列的证书的哪个特定部分。 Apple提供的初始商家证书为.cer格式。 我已将公钥从中提取为.pem格式。比我试过两个拿哈希 - > public64的base64encode(----- BEGIN CERTIFICATE -----和----- END CERTIFICATE -----之间的字符串)和 采取base64解码.pem的哈希,我认为应该是.der和base 64编码它。

两者都未能与Apple Pay收到的价值相匹配。它有不同的长度我的base64编码散列有88个字符长度,而publicKeyHash字段长度为44个字符。

当我尝试基于64解码publicKeyHash时,我有不可改变的字符,如“D đ $ f @c $ WP ” 但根据Apple文档,应该有sha-256哈希,它不能包含这样的符号。

有人可以解释一下我应该执行哪些具体步骤来完成此商家证书检查吗?

4 个答案:

答案 0 :(得分:2)

在我的情况下,主要问题和解决方案是使用付款处理证书的公钥哈希和 商家身份证书公钥哈希,女巫我试图从支付令牌与PublicKeyHash进行比较。    在我的借​​口中,我可以说Apple Documentation后面的文字非常含糊不清:

  

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

由于我们有两种证书商家和付款处理。对我来说很明显,文档中的商家证书是商家身份证明。

仅在重新阅读付款处理证书说明

之后
  

付款处理证书。用于安全的证书   转移支付数据。 Apple Pay服务器使用付款处理   证书的公钥加密付款数据。使用私人   处理付款时解密数据的关键。

来自Apple Pay JS文档,我意识到自己的错误。

所以我希望我的经验可以帮助别人不要踩到同样的耙子)

答案 1 :(得分:2)

这个问题和接受的答案在细节上仍然有点模糊,所以这里有一个经过精确测试的方法,用于检查token.paymentData.header.publicKeyHash是否符合Apple Pay支付处理证书:

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));
    }
}

答案 2 :(得分:0)

可惜我无法找到openssl命令来直接从证书中提取哈希。因此,您必须先创建公共密钥才能获取公共密钥哈希。有两种提取公钥的方法。

第1步

A。通过您的ecc私钥(付款处理私钥)

openssl ec -in ecc_private_key.key -pubout -out ec_public_key.pem

OR

B。从Apple Pay门户下载的证书中(上传付款处理CSR之后)

openssl x509 -inform der -in apple_pay.cer -pubkey -noout > apple_pay_public_key.pem

两者都会以以下格式为您提供公钥

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENGbyXUzeZTdeyyNuXyc0nMzXmnLl
xMwd/t/sCZr3RPhytPbZpR/V4/xHqN/MVzozzq30I0/eUefbThEBl236Og==
-----END PUBLIC KEY-----

第2步
您可以使用以下代码从上述公共密钥中提取base64哈希,切记删除页眉/页脚和换行符。

我希望我能弄清楚如何使用openssl工具从公钥中获取哈希值,但是无论如何,遵循c#代码对我有用。它非常简单易用,可移植到java / python / php或任何您的喜好。或者只是通过ideone.com

在线使用以下代码
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验证您是否需要加载正确的私钥当您当前的证书即将到期(或出于任何原因而被吊销)时,否则系统可能会在短时间内无法接受交易。根据我的一次遭遇,在门户中按激活后,新的支付处理键才激活,苹果花了一个多小时。

答案 3 :(得分:0)

首先,原始问题的答案似乎相隔数月。其次,所有答案似乎都缺乏关键的信息。 Payment Token Format Reference步骤2的唯一原因是您可以使用多个付款处理证书。如果这样做,Apple可能会使用任何人来加密数据。 如果您只有一张付款处理证书,则可以跳过此步骤,只需使用其私钥即可。毕竟,第二步的最终结果是获得用于加密支付数据的支付处理证书的私钥。