我在 .net Framework 4.5 中有一个 Web 服务,它使用 SOAP12 http 请求调用端点。如果没有 SSL 协议,它可以正常工作,但现在我需要添加 SSL 协议,因此使其在特定端口上使用 https。我可以更改代码以强制使用 TLS 1.2,并在必要时更改为 https,它在我的本地计算机和远程服务器上都可以正常工作。
问题是当我在客户端服务器上运行此代码时,该服务器有更多安全屏障,如代理、防火墙等。
在说我应该在谷歌上搜索很多人都有这个问题之前,我知道并尝试了我能找到的所有方法,但没有一个起作用......
出于隐私和安全原因,我将替换一些名称。
端口不是 443,但我替换只是为了说明。
这就是我设置一切的方式:
应用程序配置:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="GetIdContosoBinding">
<security mode="Transport">
<transport clientCredentialType="None">
</transport>
</security>
</binding>
<binding name="GetByIdBinding">
<security mode="Transport">
<transport clientCredentialType="None">
</transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://api.endpoint.com:443/web/Contoso/GetById" binding="basicHttpBinding" bindingConfiguration="GetIdContosoBinding" contract="DecodeContosoId.GetIdContoso" name="GetIdContoso"/>
<endpoint address="https://api.endpoint.com:443/web/ContosoStatus/GetById" binding="basicHttpBinding" bindingConfiguration="GetByIdBinding" contract="GetOrderStatus.ContosoStatus" name="ContosoStatus"/>
</client>
</system.serviceModel>
服务1.cs:
public void Start() {
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
// my logic here
}
// more logic
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
Logger.Info(LogType.File, $"There are no SSL errors");
return true;
}
Logger.Error(LogType.File, $"There is an error on SSL: " + sslPolicyErrors.ToString());
return false;
}
我进行 Http 调用的代码:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Logger.Info(LogType.File, "Setting security protocol to {protocol}", ServicePointManager.SecurityProtocol.ToString());
var decoder = new ContosoClient();
// This is new, just trying something
decoder.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication()
{
CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust,
TrustedStoreLocation = StoreLocation.LocalMachine
};
var contoso = decoder.getContosoById(new contosoInput
{
LANG = "it",
YEAR = 2024,
ID = id
});
return tracking;
错误如下:
2024-05-23 12:57:21.8869 logFile Info Test.BusinessLogic.Contoso.ContosoHelper - GetContoso Setting security protocol to "Tls12"
2024-05-23 12:57:22.1629 logFile Error Test.BusinessLogic.Contoso.ContosoHelper - GetContoso System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'api.endpoint.com:443'. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Test.BusinessLogic.GetContosoStatus.Contoso_GetById.Contoso_id(Contoso_idRequest request)
at Test.BusinessLogic.GetContosoStatus.Contoso_IdServicesClient.Test.BusinessLogic.GetContosoStatus.Contoso_IdServices.Contoso_id(Contoso_idRequest request)
at Test.BusinessLogic.Contoso.ContosoHelper.GetContoso(Int64 id, String year)
这是我为解决问题所做的一系列事情。
System.Net Information: 0 : [10116] Current OS installation type is 'Server'.
System.Net Verbose: 0 : [10116] Entering WebRequest::Create(https://api.endpoint.com:443/web/[cut path endpoint just for privacy])
System.Net Verbose: 0 : [10116] Entering HttpWebRequest#[requestId]::HttpWebRequest(https://api.endpoint.com:443/web/[cut path endpoint just for privacy]#[cut id value])
System.Net Information: 0 : [10116] RAS supported: True
System.Net Verbose: 0 : [10116] Exiting HttpWebRequest#[requestId]::HttpWebRequest()
System.Net Verbose: 0 : [10116] Exiting WebRequest::Create() -> HttpWebRequest#[requestId]
System.Net Error: 0 : [10116] Can't retrieve proxy settings for Uri 'https://api.endpoint.com:443/web/[cut path endpoint just for privacy]'. Error code: 12180.
System.Net Verbose: 0 : [10116] Entering ServicePoint#51037211::ServicePoint(api.endpoint.com:443)
System.Net Information: 0 : [10116] Associating HttpWebRequest#[requestId] with ServicePoint#51037211
System.Net Verbose: 0 : [10116] Entering HttpWebRequest#[requestId]::GetRequestStream()
System.Net Information: 0 : [10116] Associating Connection#[conn id] with HttpWebRequest#[requestId]
System.Net Information: 0 : [10116] Connection#[conn id] - Created connection from [my server address] to [remote server address].
System.Net Information: 0 : [10116] TlsStream#[tlsstreamid]::.ctor(host=api.endpoint.com, #certs=0, checkCertificateRevocationList=False, sslProtocols=Tls12)
System.Net Information: 0 : [10116] Associating HttpWebRequest#[requestId] with ConnectStream#[streamid]
System.Net Verbose: 0 : [10116] Exiting HttpWebRequest#[requestId]::GetRequestStream() -> ConnectStream#[streamid]
System.Net Verbose: 0 : [10116] Entering ConnectStream#[streamid]::Write()
System.Net Verbose: 0 : [10116] Data from ConnectStream#[streamid]::Write
System.Net Verbose: 0 : [10116] 00000000 : [CUT ENVELOPE DATA for privacy]
System.Net Verbose: 0 : [10116] Exiting ConnectStream#[streamid]::Write()
System.Net Verbose: 0 : [10116] Entering ConnectStream#[streamid]::Close()
System.Net Verbose: 0 : [10116] Exiting ConnectStream#[streamid]::Close()
System.Net Verbose: 0 : [10116] Entering HttpWebRequest#[requestId]::GetResponse()
System.Net Information: 0 : [10116] HttpWebRequest#[requestId] - Request: POST /web/[cut path endpoint just for privacy] HTTP/1.1
System.Net Information: 0 : [10116] ConnectStream#[streamid] - Sending headers
{
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://contoso.wsbeans.iseries/contosoIdServices/contosoidRequest"
Host: api.endpoint.com:443
Content-Length: 469
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
}.
System.Net Information: 0 : [10116] SecureChannel#48888762::.ctor(hostname=api.endpoint.com, #clientCertificates=0, encryptionPolicy=RequireEncryption)
System.Net Information: 0 : [10116] Enumerating security packages:
System.Net Information: 0 : [10116] Negotiate
System.Net Information: 0 : [10116] NegoExtender
System.Net Information: 0 : [10116] Kerberos
System.Net Information: 0 : [10116] NTLM
System.Net Information: 0 : [10116] TSSSP
System.Net Information: 0 : [10116] pku2u
System.Net Information: 0 : [10116] WDigest
System.Net Information: 0 : [10116] Schannel
System.Net Information: 0 : [10116] Microsoft Unified Security Protocol Provider
System.Net Information: 0 : [10116] Default TLS SSP
System.Net Information: 0 : [10116] CREDSSP
System.Net Information: 0 : [10116] SecureChannel#48888762 - Left with 0 client certificates to choose from.
System.Net Information: 0 : [10116] SecureChannel#48888762::.AcquireClientCredentials, new SecureCredential() (flags=(ValidateManual, NoDefaultCred, SendAuxRecord, UseStrongCrypto), m_ProtocolFlags=(Tls12Client), m_EncryptionPolicy=RequireEncryption)
System.Net Information: 0 : [10116] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent = Outbound, scc = System.Net.SecureCredential)
System.Net Information: 0 : [10116] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = api.endpoint.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [10116] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=164, returned code=ContinueNeeded).
System.Net Information: 0 : [10116] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = 40f60c0:41a9628, targetName = api.endpoint.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [10116] InitializeSecurityContext(In-Buffers count=2, Out-Buffer length=0, returned code=IllegalMessage).
System.Net Error: 0 : [10116] Exception in HttpWebRequest#[requestId]:: - The request was aborted: Could not create SSL/TLS secure channel..
System.Net Error: 0 : [10116] Exception in HttpWebRequest#[requestId]::GetResponse - The request was aborted: Could not create SSL/TLS secure channel..
最后,我的日志中出现了同样的错误。
openssl s_client -connect api.endpoint.com:443 -tls1_2
Connecting to [REDACTED]
CONNECTED(000001B0)
depth=2 C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
verify error:num=19:self-signed certificate in certificate chain
verify return:1
depth=2 C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
verify return:1
depth=1 C=US, O=DigiCert Inc, OU=www.digicert.com, CN=GeoTrust TLS RSA CA G1
verify return:1
depth=0 C=IT, L=BOLOGNA, O=BRT S.P.A., CN=*.brt.it
verify return:1
---
Certificate chain
0 s:C=IT, L=BOLOGNA, O=BRT S.P.A., CN=*.brt.it
i:C=US, O=DigiCert Inc, OU=www.digicert.com, CN=GeoTrust TLS RSA CA G1
a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
v:NotBefore: Jun 26 00:00:00 2023 GMT; NotAfter: Jul 24 23:59:59 2024 GMT
1 s:C=US, O=DigiCert Inc, OU=www.digicert.com, CN=GeoTrust TLS RSA CA G1
i:C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Nov 2 12:23:37 2017 GMT; NotAfter: Nov 2 12:23:37 2027 GMT
2 s:C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
i:C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Aug 1 12:00:00 2013 GMT; NotAfter: Jan 15 12:00:00 2038 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
[CERTIFICATE CONTENT REDACTED]
-----END CERTIFICATE-----
subject=C=IT, L=BOLOGNA, O=BRT S.P.A., CN=*.brt.it
issuer=C=US, O=DigiCert Inc, OU=www.digicert.com, CN=GeoTrust TLS RSA CA G1
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 4855 bytes and written 306 bytes
Verification error: self-signed certificate in certificate chain
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 4096 bit
Secure Renegotiation IS supported
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: [REDACTED]
Session-ID-ctx:
Master-Key: [REDACTED]
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket: [REDACTED]
Start Time: [REDACTED]
Timeout : 7200 (sec)
Verify return code: 19 (self-signed certificate in certificate chain)
Extended master secret: yes
---
有些东西不太正常...
可能尝试了更多的事情,比如代码中的注释部分,但我真的不知道发生了什么。我的客户说他们已开放对此端点的访问,并且代理也已针对端口和主机名开放。如果有人知道发生了什么,我将非常感激
问题是服务器没有正确的套件密码,我以为有,但我错了。谢谢大家的宝贵时间。