微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

HttpClient SSL 握手失败自签名证书 - Swish

如何解决HttpClient SSL 握手失败自签名证书 - Swish

我真的会拔头发。这应该不难实现,但无论如何我无法让它工作。我正在尝试实施瑞典 Swish API 进行支付。我们所需要的只是发送一个有效负载并向 httpclienthandler 添加一个证书。

我正在尝试实现 PaymentRequest 方法,如下所述:https://developer.swish.nu/api/payment-request/v2

我的代码如下,首先是一个配置类:

public class SwishApiDetails
{
    public string BaseUrl { get; set; } // Base URL for the API
    public string CallbackUrl { get; set; } // Optional callback URL
    public string ClientCertificate { get; set; } // Client certificate thumbprint
    public string RootCertificateV1 { get; set; } // First CA certificate
    public string RootCertificateV2 { get; set; } // Second CA certificate
}

实际 API 调用代码(是的,我知道我没有处理客户端,但这不是现在的问题(除非是))

public class SwishApi
{
    private readonly HttpClient _client;
    private readonly SwishApiDetails _configuration;

    public SwishApi(SwishApiDetails configuration)
    {
        _configuration = configuration;
        var handler = new httpclienthandler
        {
            ServerCertificateCustomValidationCallback = (
                sender,certificate,chain,sslPolicyErrors) => true,ClientCertificateOptions = ClientCertificateOption.Manual
        };

        var thumbprints = new List<string>
        {
            _configuration.ClientCertificate,_configuration.RootCertificateV1,_configuration.RootCertificateV2
        };

        var store = new X509Store(StoreName.My,StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);

        foreach (var thumbprint in thumbprints)
        {
            var certificates = store.Certificates.Find(X509FindType.FindByThumbprint,thumbprint,false);
            handler.ClientCertificates.AddRange(certificates);
        }

        _client = new HttpClient(handler) {BaseAddress = new Uri(_configuration.BaseUrl)};
    }

    public async Task<(bool HasError,string Message)> MakePaymentRequest(
        int amountToPay,string reference,string phoneNumber,string receiverAlias,string messagetoCustomer)
    {
        var phoneAlias = phoneNumber.Replace(" ","").Replace("+","");
        if (phoneAlias.StartsWith("0")) phoneAlias = phoneAlias.Substring(1,phoneAlias.Length);

        var result = await _client.SendAsync(new HttpRequestMessage
        {
            Method = HttpMethod.Put,RequestUri = new Uri($"{_configuration.BaseUrl}/api/v2/paymentrequests/{reference}"),Content = JsonContent.Create(new
            {
                amount = amountToPay,payerAlias = phoneAlias,payeeAlias = receiverAlias,message = messagetoCustomer,payeePaymentReference = reference,currency = SwishDefaults.Currency.Sek,callbackUrl = _configuration.CallbackUrl
            })
        });

        return result.IsSuccessstatusCode
            ? (false,string.Empty)
            : (true,await result.Content.ReadAsstringAsync());
    }
}

为了测试这一切,我使用了这个代码

public class Test
{
    private readonly SwishApi _swish;

    public test()
    {
        _swish = new SwishApi(new SwishApiDetails
        {
            BaseUrl = "https://cpc.getswish.net/swish-cpcapi",CallbackUrl = null,ClientCertificate = "F06644FAF53150D5B31716ABF121FE112A225AF1",// Local thumbprint
            RootCertificateV1 = "A8985D3A65E5E5C4B2D7D66D40C6DD2FB19C5436",// Local thumbprint
            RootCertificateV2 = "03BFF7B54C712504C5BE5A8528163C931618A3C0" // Local thumbprint
        });
    }

    [Fact]
    public async Task TestPaymentRequest()
    {
        var (hasError,_) = await _swish.MakePaymentRequest(
            1,Guid.NewGuid().ToString("N").toupper(),"4671111111","Swish Test","Testing");

        Assert.False(hasError);
    }
}

证书从这里下载:https://assets.ctfassets.net/4dca8u8ebqnn/5B6HqHPnsnGf0klDoeQSJh/1d4a6bf66a1269859cf00c01b312c601/mss_test_1.9.zip

它们在测试环境中是公开的。

证书不是真正的 CA,它们是由 Swish 自己签署的,因此可能存在一些问题。除此之外,我真的不知道出了什么问题,也不知道为什么其他人可以让它发挥作用。

可能是操作系统特定的,还是我机器上的密码套件被破坏了?

如果您想尝试一下,请转到此存储库:https://github.com/lhammarstrom/swish-net

如果你想用本地证书文件试试,那么你可以去这个分支:https://github.com/lhammarstrom/swish-net/tree/feature/with_cert (feature/with_cert)。客户端证书包含在测试项目的文件中。

另外,为了澄清,我得到的错误是:

System.Net.Http.HttpRequestException: The SSL connection Could not be established,see inner exception.

System.Net.Http.HttpRequestException
The SSL connection Could not be established,see inner exception.
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async,Stream stream,SslClientAuthenticationoptions sslOptions,CancellationToken cancellationToken)
   at System.Net.Http.httpconnectionPool.ConnectAsync(HttpRequestMessage request,Boolean async,CancellationToken cancellationToken)
   at System.Net.Http.httpconnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request,CancellationToken cancellationToken)
   at System.Net.Http.httpconnectionPool.GethttpconnectionAsync(HttpRequestMessage request,CancellationToken cancellationToken)
   at System.Net.Http.httpconnectionPool.SendWithRetryAsync(HttpRequestMessage request,Boolean doRequestAuth,CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request,CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request,HttpCompletionoption completionoption,Boolean emitTelemetryStartStop,CancellationToken cancellationToken)
   at Swish.Services.SwishApi.MakePaymentRequest(Int32 amountToPay,String reference,String phoneNumber,String receiverAlias,String messagetoCustomer) in /Users/leni/Projects/Swish/Swish/Services/SwishApi.cs:line 73
   at Swish.Tests.Test.TestPaymentRequest() in /Users/leni/Projects/Swish/Swish.Tests/Tests.cs:line 30
   at Xunit.Sdk.TestInvoker`1.<>c__displayClass48_1.<<InvokeTestMethodAsync>b__1>d.MoveNext() in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\Runners\TestInvoker.cs:line 264
--- End of stack trace from prevIoUs location ---
   at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in C:\Dev\xunit\xunit\src\xunit.execution\Sdk\Frameworks\ExecutionTimer.cs:line 48
   at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in C:\Dev\xunit\xunit\src\xunit.core\Sdk\ExceptionAggregator.cs:line 90

System.Security.Authentication.AuthenticationException
Authentication Failed,see inner exception.
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter,Boolean receiveFirst,Byte[] reAuthenticationData,Boolean isApm)
   at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async,CancellationToken cancellationToken)

Interop+AppleCrypto+SslException
handshake failure
  Exception doesn't have a stacktrace

编辑:

我已遵循本指南 (https://johan.driessen.se/posts/Calling-the-Swish-Payment-API-from-Azure-AppService/)。他们让它工作,而我没有。此外,这个声称可以在 .NET 5 (https://github.com/RickardPettersson/swish-api-csharp) 上运行的存储库也不能在我的机器上运行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?