带有适用于Android和iOS的相互证书的邮件安全性

时间:2018-09-20 15:05:19

标签: android ios wcf wcf-security android-ksoap2

我想问以下问题。我们有一个适用于Android和iOS的移动应用程序,可与.NET服务器交换数据。

对于Android,使用kso​​ap2库,而对于iOS,则使用带有AEXML库的Alamofire。

我们希望为服务器和应用之间的通信启用加密,特别是带有互证书(https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/message-security-with-mutual-certificates)的邮件安全性

我无法找到有关Android或iOS客户端如何加密/解密请求/响应的任何信息。

请提供任何相关信息?

谢谢!

3 个答案:

答案 0 :(得分:3)

对于iOS部分。

默认情况下,Alamofire将使用安全框架提供的Apple内置验证来评估服务器提供的证书链。

尽管这可以确保证书链有效,但不能防止中间人(MITM)攻击或其他潜在漏洞。

为了减轻MITM攻击,处理敏感客户数据或财务信息的应用程序应使用ServerTrustPolicy提供的证书或公钥固定。

ServerTrustPolicy 通过安全HTTPS连接连接到服务器时,ServerTrustPolicy枚举会评估通常由URLAuthenticationChallenge提供的服务器信任。

let serverTrustPolicy = ServerTrustPolicy.pinCertificates(
    certificates: ServerTrustPolicy.certificates(),
    validateCertificateChain: true,
    validateHost: true
)

服务器信任评估有许多不同的情况,使您可以完全控制验证过程:

performDefaultEvaluation:使用默认的服务器信任评估,同时允许您控制是否验证质询提供的主机。

pinCertificates:使用固定证书来验证服务器信任。如果固定证书之一与服务器证书之一匹配,则服务器信任被视为有效。

pinPublicKeys:使用固定的公钥来验证服务器信任。

如果固定的公用密钥之一与服务器证书公用密钥之一匹配,则服务器信任被视为有效。

disableEvaluation:禁用所有评估,这反过来将始终将任何服务器信任视为有效。

customEvaluation:使用关联的闭包来评估服务器信任的有效性,从而使您可以完全控制验证过程。谨慎使用。

  

AlamoFire documentation

对于Android而言,我并不熟悉,但是遇到了有人问同样的事情,并且得到了答案

  

您需要做的只是将证书安装到Web服务器中,然后调用https://my.webservice.url/之类的Web服务URL,而不是http://my.webservice.url/

     

如果您的证书是自签名证书,则表示您没有   是从证书颁发机构购买的,则需要设置   SSLSocketFactory。您可以查看有关如何执行此操作的项目Wiki:   http://code.google.com/p/ksoap2-android/wiki/CodingTipsAndTricks#How_to_set_the_SSLSocketFactory_on_a_https_connection__in_order

选中Here

This可能也有帮助

更新:我已经找到了这个框架SOAPEEngine 这个。 支持基本,摘要和NTLM身份验证,WS-Security,客户端证书和自定义安全标头。

您也可以查看其example以获得更多说明。

答案 1 :(得分:3)

使用WS-Security协议通过将安全属性mode设置为Message,可以使用WCF进行消息加密。毫无疑问,到目前为止,WS-Security在Android和iOS平台上并不十分流行,主要是因为它已被其他技术(例如HTTPS)所取代,因此您在现有库方面的选择并不多。 not even Microsoft-owned Xamarin supports it讲了很多话。

首先,它是WS-Security的缩写,该协议提供了三种增强消息安全性的主要方法:

  • 通过安全令牌进行身份验证
  • 签署SOAP消息
  • SOAP消息的加密

因此,一个合规的实现实际上应该提供所有这三个功能,但是我们在这里最感兴趣的是加密,因为从问题和注释看来,您的身份验证部分正在起作用。

因此,假设我们正在寻找一个提供最少的WCF与WS-Security签名和加密兼容性的移动平台库:

Android

在Android上,最接近您需求的是WSS-Client for Android。这个项目:

  

...实现了OASIS Web服务安全性(WSS)标准,用于   Android平台,并提供XML加密和XML签名   用于平板电脑和智能手机。

请注意,这是GPL许可的软件。自述文件要求与作者联系以获取商业许可的详细信息。但是,它似乎可以满足您的需求。与服务器协商密钥交换后,要使用SOAPUtil类加密先前构造的SOAP消息,您将执行以下操作:

SOAPMessage message = SOAPUtil.createSOAPMessage();
//... Populate the message (possibly with another library)
SecCrypto serverCrypto = new SecCrypto(serverCertificate, null);
SecCrypto clientCrypto = new SecCrypto(clientPublicKey, clientPrivateKey);
SOAPMessage securedMessage = SOAPUtil.secureSOAPMessage(message, new HashMap<String,String>(SecConstants.REQ_ENCRYPT_SIGN, "yes"), clientCrypto, serverCrypto);
//...
SOAPMessage returnedSecuredMessage = SOAPUtil.sendSOAPMessage(context, securedMessage, endpoint,  cryptoParams);
SOAPMessage returnedMessage = SOAPUtil.validateSOAPMessage(returnedSecuredMessage, new HashMap<String,String>(SecConstants.RES_DECRYPT_VERIFY, "yes", decCrypto);

尽管如此,准备进行大量配置工作和调试以使其符合服务器的需求。

如果您正在寻找更新,更活跃的产品,Quasar Development提供了适用于Android的WS-Security实现。

iOS

iOS方面的情况看起来更加暗淡。有一些图书馆声称对WSS的支持程度不同,但是似乎都不符合您的需求:

  • 起初SOAPEngine看起来最有希望 支持WS-Security。但是,在脚注中说它有一个 仅支持WCF basicHttpBinding的限制。这个 如果为true,则实际上可以。您在示例代码中使用的绑定 问题中链接到的是wsHttpBinding,但这很重要 注意wsHttpBindingbasicHttpBinding均受支持 通过WS-Security进行加密。区别在于 wsHttpBinding默认支持WS-Security(而它需要 basicHttpBinding启用),它还支持 WS-ReliableMessaging和some other features,您可能会也可能不会 关心。但是basicHttpBinding是用于 与其他技术的兼容性。所以为了有 WCF服务器上的WS-Security加密并最大程度地提高了兼容性 与其他技术同时使用,可以使用 basicHttpBinding并通过以下方式启用WS-Security签名和加密: 将mode安全属性设置为Message。随着 Message属性,from the docs

      

    使用SOAP消息安全性提供安全性。默认情况下,主体   已加密并签名。对于此绑定,系统要求   服务器证书将带外提供给客户端。唯一的   此绑定的有效ClientCredentialType是证书。

    但这没有用,因为SOAPEngine不支持 加密消息(或者至少我找不到对此的任何支持) 在API中)。它支持的唯一WS-Security功能是 身份验证。因此,声称它支持WS-Security的说法似乎 误导,因为支持非常有限。

  • ServiceNow对WS-Security的支持非常有限。它只是 支持验证服务器签名。没有加密或签名 客户端。
  • Chilkat有一些基本的XML支持,并且有示例 WS-Security认证的代码。我没有看到任何支持或 WS-Security加密的示例代码。

因此,就我所知,对于iOS,您有两个选择:

  • 选择一个最能满足您其他需求的现有库 并与开发人员联系,看看是否可以让他们添加 您需要的WS-Security功能。
  • 实施最低限度的功能 你需要自己。 The spec实际上并不那么复杂, 那里有针对非移动平台的示例代码 可以用作指导,例如WSS4J。

答案 2 :(得分:0)

在Android中:

我使用kasoap2调用Web服务,但是在调用之前,要启用与客户端证书的相互身份验证,您需要使用客户端身份验证密钥(KeyManager)初始化SSLContext。 为此,您必须在KeyStore对象中加载证书和相应的密码,我的证书是* .pfx文件。我确定了一个“ PKCS12” KeyStore实例。然后,您需要一个KeyManagerFactory对象来获取KeyManager数组。我使用“ PKIX” KeyManagerFactory实例。需要KeyManager数组来初始化SSLContext。

这里是一个例子:

public void enableMutualAuthentication(String filename, String password) {
    try {
        // InputStream to read the certificate file
        FileInputStream cert = new FileInputStream(filename);
        char[] pass = password.toCharArray();

        KeyStore keystore = KeyStore.getInstance("PKCS12");
        keystore.load(cert ,pass);
        cert.close();

        KeyManagerFactory keymanagerfactory = javax.net.ssl.KeyManagerFactory.getInstance("PKIX");
        keymanagerfactory.init(keystore, pass);
        KeyManager[] keymanagers = keymanagerfactory.getKeyManagers();

        // This is not for the mutual authentication.
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        } };

        // Install the mutual authentication manager
        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(keymanagers, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    }
}

检查那些链接,对我最有帮助。

https://chariotsolutions.com/blog/post/https-with-client-certificates-on/ http://callistaenterprise.se/blogg/teknik/2011/11/24/android-tlsssl-mutual-authentication/