web-services - 通过 SSL 的 MonoTouch Web 服务请求获取 'authentication or decryption has failed'

标签 web-services soap ssl crash xamarin.ios

通过 SSL 的 Web 服务请求在 Monotouch v4.0.4.1 上引发 WebException:

'Error getting response stream (Write: The authentication or decryption has failed)'

由于服务器的 SSL 证书是自签名的(顺便说一句,我认为它不是 X.509),因此我使用 ServicePointManager.ServerCertificateValidationCallback 绕过了证书验证。完全相同的代码在 Windows .NET 上运行良好,其中 Web 服务调用返回正确的结果。在 Monotouch 上添加 Writeline 显示永远不会到达 ServerCertificateValidationCallback 委托(delegate)代码。

注意:虽然可能不相关,但请求的内容是带有嵌入式 WS-Security UsernameToken 的 SOAP。

  1. 有人在 MonoTouch 上有类似的东西吗?见过类似症状的报告,但没有解决。代码和堆栈跟踪如下,欢迎任何评论。如果需要,可以通过电子邮件发送独立的测试用例。

  2. 我发现有一种替代方法,使用 certmgr.exe 将自签名服务器证书存储在本地信任存储中,但似乎无法在 MonoTouch 发行版中找到该应用程序。有人能指点我吗?

..

public class Application
{
    static void Main (string[] args)
    {
        UIApplication.Main (args);
    }
}

// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
    // This method is invoked when the application has loaded its UI and its ready to run
    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        // If you have defined a view, add it here:
        // window.AddSubview (navigationController.View);

        string soapResponse;
        string soapRequest = @" SOAP envelope is here but omitted for brevity ";
        soapResponse = WebService.Invoke("myOperation", soapRequest);
        window.MakeKeyAndVisible ();
        return true;
    }

    // This method is required in iPhoneOS 3.0
    public override void OnActivated (UIApplication application)
    {
    }
}


public class WebService
{
    public static string Invoke(string operation, string soapRequest)
     // Input parameters: 
    //  operation = WS operation name
    //  soapRequest = SOAP XML request
    // Output parameter:
    //  SOAP XML response
    {
        HttpWebResponse response;
        try
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
            ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, ssl) => true;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://myserver.com:7570/MyEndpoint");
            request.Method = "POST";
            request.Headers.Add("SOAPAction", "/MyEndpoint/" + operation);
            request.ContentType = "text/xml;charset=UTF-8";
            request.UserAgent = "Smartphone";
            request.ContentLength = soapRequest.Length;
            request.GetRequestStream().Write(System.Text.Encoding.UTF8.GetBytes(soapRequest), 0, soapRequest.Length);
            request.GetRequestStream().Close();
            response = (HttpWebResponse)request.GetResponse();
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }
        catch (WebException e)
        {
            throw new WebException(e.Message);
        }
    }
} 

堆栈跟踪(一些名称已更改,以保护无辜者,可根据要求提供原始版本):

WS.WebService.Invoke (operation="myOperation", soapRequest="<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" \n\txmlns:ns1=\"http://mycompany/Common/Primitives/v1\" \n\txmlns:ns2=\"http://mycompany/Common/actions/externals/Order/v1\" \n\txmlns:ns3=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">\n\t<SOAP-ENV:Header> <wsse:Security SOAP-ENV:mustUnderstand=\"1\" \n\txmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"> \n\t<wsse:UsernameToken wsu:Id=\"UsernameToken-1\" \n\txmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"> \n\t<wsse:Username>myusername</wsse:Username> <wsse:Password \n\tType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">mypw</wsse:Password> \n\t<wsse:Nonce>{0}</wsse:Nonce> \n\t<wsu:Created xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">{1}</wsu:Created> \n\t</wsse:UsernameToken> </wsse:Security> \n\t</SOAP-ENV:Header><SOAP-ENV:Body><ns2:tp_getOrderDetailRequest><ns2:header><ns1:source>TEAM</ns1:source>\n\t<ns1:userAccessKey>12345678901234567</ns1:userAccessKey></ns2:header>\n\t<ns2:OrderId>myid1</ns2:OrderId>\n\t<ns2:OrderId>myid2</ns2:OrderId>\n\t</ns2:tp_getOrderDetailRequest>\n\t</SOAP-ENV:Body>\n\t</SOAP-ENV:Envelope>") in /Users/billf/Projects/WS/WS/Main.cs:103
WS.AppDelegate.FinishedLaunching (app={MonoTouch.UIKit.UIApplication}, options=(null)) in /Users/billf/Projects/WS/WS/Main.cs:52
MonoTouch.UIKit.UIApplication.Main (args={string[0]}, principalClassName=(null), delegateClassName=(null)) in /Developer/MonoTouch/Source/monotouch/monotouch/UIKit/UIApplication.cs:26
MonoTouch.UIKit.UIApplication.Main (args={string[0]}) in /Developer/MonoTouch/Source/monotouch/monotouch/UIKit/UIApplication.cs:31
WS.Application.Main (args={string[0]}) in /Users/billf/Projects/WS/WS/Main.cs:18

最佳答案

MonoTouch(就像 Mono)不支持 TLS_DH* 密码套件(例如 TLS_DHE_DSS_WITH_AES_128_CBC_SHA)。

当服务器配置为仅接受它们时,协商阶段会很早就失败(发送客户端 Hello 消息后从服务器收到警报),这解释了为什么从未调用回调.

确保您的服务器允许更传统的密码套件,例如非常安全(但速度较慢)的 TLS_RSA_WITH_AES_256_CBC_SHA 或更快(且非常常见)的密码套件:TLS_RSA_WITH_RC4_128_[MD5|SHA] 和 Mono[Touch] 应该可以很好地使用它们。

请注意,这与 SOAP 或 Web 服务(甚至 X.509 证书)无关 - 它只是普通的 SSL。

关于web-services - 通过 SSL 的 MonoTouch Web 服务请求获取 'authentication or decryption has failed',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6927140/

相关文章:

.NET Web 服务本地测试

node.js - Nodejs Soap api 调用返回 "Unexpected root element of WSDL or include"

java - 如何使用WS-Discovery规范在Java中发现网络上的ONVIF设备?

go - go - 如何使用证书存储中的证书并在 gin 框架中运行 TLS?

.net - 随机 "could not establish secure channel for SSL/TLS"错误

java - 如何防止 JBoss AS 7.x 部署 Web 应用程序依赖项中包含的 Web 服务

php - SoapServer() 调用无法访问 wsdl 文件

android - 如何从 Soap 对象获取对 android 中字符串的响应?

postgresql - 连接到 Postgres AWS RDS 实例 - "certificate verify failed"

Java 调用 Web 服务不更新 boolean 属性