2

我无法在我的 Apple Pay 沙盒环境中验证商家。取自https://developer.apple.com/reference/applepayjs/applepaysession#2166532,一旦我server then calls the Start Session endpoint at the provided URL出现 500 错误。

我已经挖掘了,这个 500 错误发生在网络层的某个地方。如苹果页面(https://developer.apple.com/reference/applepayjs/)中所列,我需要满足以下要求:

  1. 所有包含 Apple Pay 的页面都必须通过 HTTPS 提供。完成,服务器在站点范围内具有 ssl/https
  2. 要启用商家验证,您的服务器必须允许通过 HTTPS(端口 443 上的 TCP)访问下面清单 1 中提供的 Apple Pay IP 地址。完成,服务器对端口 443 上的所有 ip 开放
  3. 您的服务器必须支持传输层安全 (TLS) 1.2 协议和表 1 中列出的密码套件之一。服务器确实支持 tls 1.2,因为我在 tls 1.2 上向 Apple Pay 的开发服务器发送请求(如下)

我一直在使用 Wireshark 检查发生了什么,一旦服务器处于ChangeCipherSpec阶段,在服务器将密码规范发送回客户端之后,我似乎失败了。(ssl 程序参考:https: //support.f5.com/csp/article/K15292)。正如您从我的图片中看到的那样,我正在与 Apple Pay 沙箱服务器通信,并传入错误提示的相同受支持的 tls 协议和密码套件 -> Handshake Failure (40),所以正在发生其他事情,我不知道在哪里看

在此处输入图像描述

如果您查看 ServerHello 消息,您可以看到服务器找到并接受了与客户端匹配的密码套件,该套件也匹配 Apple Pay 支持的所需密码之一 在此处输入图像描述

在此处输入图像描述

我可以根据需要添加其他详细信息

4

2 回答 2

3

问题是我们的服务器默认没有启用 TLS 1.2。启用 TLS 1.2 和禁用 TLS 1.0 解决了问题 - Win 2008

编辑

有几件事需要发生。我们的服务器在 .net 4.5 上,默认情况下不使用 tls 1.2(苹果要求使用 tls 1.2)。因此,我们将我们的解决方案升级到 .net 4.6,并为我们的请求强制使用 tls 1.2。此外,我们必须在对苹果的请求中包含商家 ID 证书(文档中没有很好地提及)。

您可以找到我在此处使用的源代码的 github 存储库 ( https://github.com/justeat/ApplePayJSSample ),但这是我的代码,我需要将其放入我的解决方案中以使事情正常进行(我还必须导出我的来自我的 mac 钥匙串的商家证书,它给了我一个 .p12 文件。我将此 .p12 文件导入到我的服务器的计算机证书存储中)

[System.Web.Http.HttpPost]
    public async Task<ContentResult> GetApplePaySession([FromBody] string url)
    {
        // http://stackoverflow.com/a/36912392/1837080
        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

        // Load the merchant certificate for two-way TLS authentication with the Apple Pay server.
        var certificate = LoadMerchantCertificate();

        // Get the merchant identifier from the certificate to send in the validation payload.
        var merchantIdentifier = GetMerchantIdentifier(certificate);

        // Create the JSON payload to POST to the Apple Pay merchant validation URL.
        var payload = new ApplePayRequest()
        {
            merchantIdentifier = merchantIdentifier,
            domainName = System.Web.HttpContext.Current.Request.Url.Host,
            displayName = "[display name from apple developer portal]"
        };

        JObject merchantSession;

        // Create an HTTP client with the merchant certificate
        // for two-way TLS authentication over HTTPS.
        using (var httpClient = CreateHttpClient(certificate))
        {
            var jsonPayload = JsonConvert.SerializeObject(payload);

            using (var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"))
            {
                // POST the data to create a valid Apple Pay merchant session.
                using (var response = await httpClient.PostAsync(url, content))
                {
                    response.EnsureSuccessStatusCode();

                    // Read the opaque merchant session JSON from the response body.
                    var merchantSessionJson = await response.Content.ReadAsStringAsync();
                    merchantSession = JObject.Parse(merchantSessionJson);
                }
            }
        }

        // Return the merchant session as JSON.
        return Content(merchantSession.ToString(), "application/json");
    }

    #region Apple Pay helper methods

    private X509Certificate2 LoadMerchantCertificate()
    {
        X509Certificate2 certificate;

        // Load the certificate from the current user's certificate store. This
        // is useful if you do not want to publish the merchant certificate with
        // your application, but it is also required to be able to use an X.509
        // certificate with a private key if the user profile is not available,
        // such as when using IIS hosting in an environment such as Microsoft Azure.
        using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
        {
            store.Open(OpenFlags.ReadOnly);

            // when using thumbprint from mmc, look at:
            // http://stackoverflow.com/a/14852713
            // there is a hidden character that you must delete
            var certificates = store.Certificates.Find(
                X509FindType.FindByThumbprint,
                "[thumbprint]",                    
                validOnly: false);

            if (certificates.Count < 1)
            {
                throw new InvalidOperationException(
                    // ReSharper disable once UseStringInterpolation
                    string.Format(
                        "Could not find Apple Pay merchant certificate with thumbprint '{0}' from store '{1}' in location '{2}'.",
                        "‎[thumpprint]", store.Name, store.Location));
            }

            certificate = certificates[0];
        }

        return certificate;
    }

    private string GetMerchantIdentifier(X509Certificate2 certificate)
    {
        // This OID returns the ASN.1 encoded merchant identifier
        var extension = certificate.Extensions["1.2.840.113635.100.6.32"];

        // Convert the raw ASN.1 data to a string containing the ID
        return extension == null ? string.Empty : Encoding.ASCII.GetString(extension.RawData).Substring(2);            
    }

    private HttpClient CreateHttpClient(X509Certificate2 certificate)
    {
        var handler = new WebRequestHandler();
        handler.ClientCertificates.Add(certificate);

        return new HttpClient(handler, disposeHandler: true);
    }

    #endregion
于 2017-04-25T20:56:03.603 回答
0

我最近刚刚经历了这个。对我来说,我必须将 PEM 和 KEY 文件合并到 PFX 中。然后我能够使用 .net core 2.1 从 ubuntu 16.04 运行启动会话调用

private HttpClient CreateHttpClient()
{
    var handler = new HttpClientHandler();
    handler.ClientCertificateOptions = ClientCertificateOption.Manual;
    handler.SslProtocols = SslProtocols.Tls12;
    handler.ClientCertificates.Add(new X509Certificate2(@"/path/yourcombinedpfx.pfx"));

    return new HttpClient(handler); ;
}
于 2018-09-13T17:44:12.847 回答