Bonjour !
Je suis en train de développer un POC pour un projet au boulot. La solution doit être viable sur Windows et sur Mac mais la techno n'est pas vraiment importante.
L'objectif est d'arriver à interroger une API sur un serveur distant sur lequel je n'ai aucune possibilité d'apporter des modifications puisqu'il est géré par un organisme tiers.
Afin de pouvoir interroger cette API, il faut fournir un certificat SSL. Ledit certificat est distribué par l'organisme qui gère l'API, seulement à certains utilisateurs triés sur le volet.
Pour cela, une clef USB (qui fait office de smart card) est donnée en main propre, avec le certificat dessus. Le certificat est signé par une autorité de confiance (Certeurope). Du coup, il est impossible (et c'est une bonne chose) d'exporter la clef dans un fichier .pem/.crt.
La seule façon que j'ai d'utiliser le certificat c'est via le navigateur (en installant les drivers fournis par la CA) ou alors via les Stores.
Le projet a commencé en Angular 5 mais je me suis vite heurté aux limitations du web (et plus précisément aux CORS https://www.html5rocks.com/en/tutorials/cors/ ).
Ayant échoué en utilisant le navigateur, je me suis dit que j'allais essayer en C# (qui est un langage fortement utilisé par ma société) pour accéder aux Stores.
J'ai donc utilisé le Framework Dotnet Core (2.0) pour pouvoir être cross-plateform. Autant j'arrive à récupérer un certificat dans le Store My/CurrentUser lorsque je suis sur windows, autant je ne trouve pas le certificat lorsque je suis sur Mac (quelque soit le store d'ailleurs).
Et pourtant quand je vais dans mon navigateur(ou dans Keychain, le gestionnaire de mdp/certificats de Mac), le certificat est bien présent.
Voici le code utilisé :
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 //** Recherche du certificat, sélection automatique s'il n'y en a qu'un, sinon une fenêtre de //** sélection est affichée. Retourne Vrai si Init ok, faux sinon. /// <summary> /// Recherche du certificat, sélection automatique s'il n'y en a qu'un, sinon une fenêtre de sélection est affichée /// </summary> /// <returns></returns> private bool InitCert() { bool functionReturnValue = false; try { X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); Console.WriteLine("Store créé."); store.Open(OpenFlags.OpenExistingOnly); Console.WriteLine("Store ouvert."); X509Certificate2Collection mesCertificats = new X509Certificate2Collection(store.Certificates); Console.WriteLine("Récupération des certificats..."); //** Si certificat pas encore initialisé, recherche du certificat if (x509 == null) { // Recherche des certificats listeDesCertificats = GetCertificatsCerteurope(mesCertificats); Console.WriteLine("Certificats chargés (s'il y en a)."); if(listeDesCertificats.Count > 0) { x509 = listeDesCertificats[0] as X509Certificate2; functionReturnValue = true; } } if (x509 == null) { Console.WriteLine("Impossible de trouver le certificat numérique." + Constants.vbCrLf + "Assurez-vous que le logiciel est correctement installé et que la clé USB est branchée."); functionReturnValue = false; return functionReturnValue; } Console.WriteLine("Certificat sélectionné : " + x509.SerialNumber); functionReturnValue = true; } catch (Exception ex) { Console.WriteLine(ex.Message); functionReturnValue = false; } return functionReturnValue; } //** Retourne une ArrayList contenant tous les certificats Certeurope disponibles dans le //** magazin. private ArrayList GetCertificatsCerteurope(X509Certificate2Collection pCollCertif) { ArrayList collectionCert = new ArrayList(); X509Certificate2 lox509 = null; try { var certifs = pCollCertif.Cast<X509Certificate2>() .Where(x => x.NotAfter >= DateTime.Today) .Where(x => x.IssuerName.Name.Contains("Certeurope")); foreach (var item in certifs) { collectionCert.Add(item); } } catch (Exception ex) { Console.WriteLine("Défaut de clé privé sur certificat " + lox509.Thumbprint); Console.WriteLine(ex.Message); } return collectionCert; }
Je tiens à préciser que ça fait un moment que je me documente sur le sujet (plus d'un mois) et que j'ai l'impression d'avoir retourné tout internet sans jamais vraiment trouver de solutions. Je suis donc à la recherche de pistes ne serait-ce que pour m'aiguiller dans mes recherches.
Tout ce que je suis arrivé à constater, c'est que la façon la plus simple de récupérer le certificat, c'est encore de passer par le navigateur du client mais que le web n'était pas une solution à mon problème pour autant (pas en l'état actuel des choses).
Mes questions sont les suivantes :
- Savez-vous comment récupérer le certificat sur Mac, via du C# ? Si oui comment (peut-être une librairie externe) ?
- Si C# n'est pas adapté, avez-vous en tête une techno qui répondrait aux attentes du projet ? Mes prochaines pistes c'est les Web Applications (Electronjs et les solutions basées sur Chromium) ou les navigateurs embarqués (bien que je sais qu'il ne gèrent pas les certificats aussi bien qu'un navigateur classique).
Toute remarque est bonne à prendre, n'hésitez pas à proposer des choses![]()
Partager