【问题标题】:Sandbox apple pay testing handshake failure沙盒苹果支付测试握手失败
【发布时间】:2017-04-20 14:25:31
【问题描述】:

我无法在我的 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 支持的所需密码之一

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

【问题讨论】:

    标签: ios iphone ssl applepayjs


    【解决方案1】:

    问题是我们的服务器默认没有启用 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
    

    【讨论】:

      【解决方案2】:

      我最近刚刚经历了这个。对我来说,我必须将 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); ;
      }
      

      【讨论】:

        猜你喜欢
        • 2021-02-20
        • 2017-08-16
        • 2015-07-11
        • 2018-12-10
        • 2021-01-30
        • 1970-01-01
        • 2018-03-26
        • 2014-11-24
        • 2019-05-17
        相关资源
        最近更新 更多