web-dev-qa-db-fra.com

Message Security avec certificats mutuels pour Android et iOS

J'aimerais poser la question suivante. Nous avons une application mobile pour Android et iOS qui échange des données avec un serveur .NET.

La bibliothèque ksoap2 est utilisée pour Android, tandis que les bibliothèques Alamofire avec AEXML sont utilisées pour iOS.

Nous souhaitons activer le cryptage pour la communication entre le serveur et les applications, en particulier Message Security avec certificats mutuels ( https://docs.Microsoft.com/en-us/dotnet/framework/wcf/feature-details/message -security-with-mutual-certificate )

Je ne suis pas en mesure de trouver la moindre information sur la manière dont le client Android ou iOS pourrait chiffrer/déchiffrer les demandes/réponses.

Pouvez-vous s'il vous plaît fournir des informations relatives? 

Merci d'avance!

11
Dimitris Makris

Le cryptage des messages avec WCF s'effectue via le protocole WS-Security, en définissant l'attribut de sécurité mode sur Message. Comme vous vous en êtes certainement rendu compte, WS-Security n’est pas très populaire sur les plateformes Android et iOS, principalement parce qu’elle a été supplantée par d’autres technologies (telles que HTTPS), de sorte que vos choix en termes de bibliothèques existantes ne sont pas abondants. Le fait que même pas la propriété de Microsoft appartenant à Xamarin en dit long.

Tout d'abord, un mot sur WS-Security, ce protocole fournit trois moyens principaux d'améliorer la sécurité des messages:

  • Authentification par jetons de sécurité
  • Signer des messages SOAP
  • Cryptage des messages SOAP

Donc, une implémentation conforme devrait vraiment fournir ces trois fonctions, mais le cryptage nous intéresse surtout, car à partir de la question et des commentaires, il semble que la partie authentification fonctionne.

Par conséquent, supposons que nous recherchions une bibliothèque de plate-forme mobile offrant une compatibilité WCF minimale avec la signature et le cryptage WS-Security:

Android

Sur Android, la réponse à vos besoins est WSS-Client for Android . Ce projet:

... implémente le standard OASIS Web Service Security (WSS) pour Plates-formes Android et rend XML Encryption et XML Signature disponible pour tablettes et smartphones.

Notez qu'il s'agit d'un logiciel sous licence GPL. Le readme dit de contacter l'auteur pour plus de détails sur la licence commerciale. Cependant, il semble faire ce que vous cherchez. Une fois que vous avez négocié l'échange de clé avec le serveur, pour chiffrer un message SOAP précédemment créé à l'aide de la classe SOAPUtil, procédez comme suit:

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);

Néanmoins, soyez prêt à faire pas mal de travail de configuration et de débogage pour le faire correspondre aux besoins de votre serveur.

Si vous recherchez un produit plus actuel et activement développé, Quasar Development _ offre une implémentation de WS-Security pour Android.

iOS

Les choses semblent beaucoup plus sombres du côté iOS. Quelques bibliothèques revendiquent différents degrés de support pour WSS, mais aucune ne semble correspondre à vos besoins:

  • Au début, (SOAPEngine } _ semble le plus prometteur, comme il le prétendSupport pour WS-Security. Cependant, dans une note de bas de page, il est indiqué qu'il existe une limitation Qui ne prend en charge que WCF basicHttpBinding. Ce Serait réellement OK si vrai. La liaison utilisée dans l'exemple de code auquel vous êtes lié dans la question est wsHttpBinding, mais il est important de noter que wsHttpBinding et basicHttpBinding prennent en charge Pour le cryptage via WS-Security. La différence est que wsHttpBinding prend en charge WS-Security par défaut (alors que cela doit être activé be est activé avec basicHttpBinding) et prend également en charge WS-ReliableMessaging et quelques autres fonctionnalités vous pouvez ou peut pascare environ. Mais le basicHttpBinding est celui destiné à la compatibilité avec d'autres technologies. Donc, pour avoir le cryptage WS-Security sur votre serveur WCF et maximiser la compatibilité Avec d'autres technologies en même temps, il serait correct d'utiliser basicHttpBinding et d'activer la signature et le cryptage WS-Security définir l'attribut de sécurité mode à Message. Avec l'attribut Message, de la documentation :

    La sécurité est assurée à l'aide de la sécurité des messages SOAP. Par défaut, le corps est crypté et signé. Pour cette liaison, le système nécessite que le certificat de serveur soit fourni au client hors bande. Le seul ClientCredentialType valide pour cette liaison est Certificate.

    Mais cela n’est d'aucune utilité, SOAPEngine ne prenant pas en charge le cryptage des messages .__ (ou du moins, je n'ai trouvé aucun support pour cela dans l'API). La seule fonction prise en charge par WS-Security est l’authentification Ainsi, l'affirmation selon laquelle il prend en charge WS-Security semble être trompeuse car le support est assez limité.

  • ServiceNow offre un support très limité pour WS-Security. Il ne supporte que la vérification des signatures de serveur. Pas de cryptage ni de signature du côté client
  • Chilkat possède un support XML rudimentaire et il existe un exemple de code Pour l'authentification WS-Security. Je n'ai vu aucun support ni exemple de code Pour le cryptage WS-Security.

Par conséquent, pour iOS, à ma connaissance, vos deux options sont les suivantes:

  • Choisissez l'une des bibliothèques existantes qui correspond le mieux à vos autres besoins .__ et contactez le développeur pour voir s'il est possible de le faire ajouter les fonctionnalités WS-Security dont vous avez besoin. 
  • Mettez en œuvre les fonctionnalités minimales minimalesvous avez besoin de vous-même. La spécification n'est en réalité pas si compliquée et Il existe un exemple de code (pour les plates-formes non mobiles) que vous pouvez utiliser comme guide, comme WSS4J par exemple.
3
mnistic

Pour la partie iOS. 

Par défaut, Alamofire évaluera la chaîne de certificats fournie par le serveur à l'aide de la validation intégrée d'Apple fournie par la structure de sécurité. 

Bien que cela garantisse la validité de la chaîne de certificats, cela n'empêche pas les attaques MITM (Man-In-the-Middle) ni d'autres vulnérabilités potentielles. 

Afin de limiter les attaques MITM, les applications traitant des données clients sensibles ou des informations financières doivent utiliser un épinglage de certificat ou de clé publique fourni par ServerTrustPolicy.

ServerTrustPolicy L'énumération ServerTrustPolicy évalue la confiance du serveur généralement fournie par un URLAuthenticationChallenge lors de la connexion à un serveur via une connexion HTTPS sécurisée.

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

Il existe de nombreux cas d'évaluation de la confiance du serveur qui vous permettent de contrôler totalement le processus de validation:

performDefaultEvaluation: utilise l'évaluation de la confiance du serveur par défaut tout en vous permettant de contrôler si vous souhaitez valider l'hôte fourni par le défi.

pinCertificates: Utilise les certificats épinglés pour valider la confiance du serveur. L'approbation du serveur est considérée comme valide si l'un des certificats épinglés correspond à l'un des certificats de serveur.

pinPublicKeys: utilise les clés publiques épinglées pour valider la confiance du serveur. 

L'approbation du serveur est considérée comme valide si l'une des clés publiques épinglées correspond à l'une des clés publiques du certificat de serveur.

disableEvaluation: Désactive toutes les évaluations qui, à leur tour, considéreront toujours toute confiance de serveur comme valide.

customEvaluation: utilise la fermeture associée pour évaluer la validité de la confiance du serveur, vous donnant ainsi un contrôle complet sur le processus de validation. Utiliser avec précaution.

AlamoFire documentation

Pour la partie Android, je ne suis pas expérimenté avec mais je suis tombé sur quelqu'un qui demandait la même chose et j'ai obtenu une réponse avec 

pour ce faire, vous devez uniquement installer votre certificat sur le serveur Web et appeler l'URL du service Web comme suit: https: //my.webservice.url/ au lieu de http: //my.webservice.url/ .

Si votre certificat est un certificat auto-signé, cela signifie que vous ne l’avez pas fait acheté à une autorité de certification, vous devrez définir le SSLSocketFactory. Vous pouvez consulter le wiki du projet pour savoir comment faire cela: http://code.google.com/p/ksoap2-Android/wiki/CodingTipsAndTricks#How_to_set_the_SSLSocketFactory_on_a_https_connection__in_order

Vérifiez Ici

This pourrait être utile aussi 

UPDATE: j'ai trouvé ce cadre SOAPEEngine this . Prend en charge l'authentification de base, Digest et NTLM, WS-Security, le certificat côté client et l'en-tête de sécurité personnalisé.

vous vérifiez son exemple pour plus de précisions. 

3
Mohmmad S

Sous Android:

J'utilise kasoap2 pour appeler les services Web, mais avant l'appel, pour activer l'authentification mutuelle avec un certificat client, vous devez initialiser un SSLContext avec les clés d'authentification client (KeyManager) . Pour cela, vous devez charger votre certificat et le mot de passe correspondant dans un objet KeyStore, mon certificat est un fichier * .pfx. Je cite une instance de "PKCS12" KeyStore. Ensuite, vous avez besoin d'un objet KeyManagerFactory pour obtenir le tableau KeyManager. J'utilise une instance "PKIX" KeyManagerFactory. Le tableau KeyManager est nécessaire pour initialiser le SSLContext.

Voici un exemple:

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();
    }
}

Vérifiez ces liens, c’est ce qui m’aide le plus.

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

0
frojas