Comment puis-je utiliser un blob de clé généré à partir de Win32 CryptoAPI dans mon application .NET ?

StackOverflow https://stackoverflow.com/questions/49211

Question

J'ai une application existante écrite en C++ pour Windows.Cette application utilise Win32 CryptoAPI pour générer une clé de session TripleDES pour crypter/déchiffrer les données.Nous utilisons le exposant d'un tour pour exporter la clé de session sous forme de blob, ce qui permet au blob d'être stocké quelque part dans un format déchiffré.

La question est de savoir comment pouvons-nous utiliser cela dans notre application .NET (C#).Le framework encapsule/enveloppe une grande partie de ce que fait CryptoAPI.Une partie du problème vient du fait que CryptAPI indique que l'algorithme TripleDES pour le Fournisseur cryptographique amélioré Microsoft est de 168 bits (3 clés de 56 bits).Cependant, le framework .NET indique que leurs clés sont de 192 bits (3 clés de 64 bits).Apparemment, les 3 octets supplémentaires dans le framework .NET sont destinés à la parité ?

Quoi qu'il en soit, nous devons lire la partie clé du blob et pouvoir l'utiliser d'une manière ou d'une autre dans notre application .NET.Actuellement, nous n’obtenons pas les résultats attendus lorsque nous essayons d’utiliser la clé dans .NET.Le décryptage échoue lamentablement.Toute aide serait grandement appréciée.

Mise à jour:

J'ai travaillé sur les moyens de résoudre ce problème et j'ai trouvé une solution que je publierai à temps.Cependant, j'apprécierais toujours les commentaires des autres.

Était-ce utile?

La solution

Introduction

Je suis enfin en train de publier la solution.J'espère que cela aidera d'autres personnes qui pourraient faire des choses similaires.Il n'y a vraiment pas beaucoup de référence à faire cela ailleurs.

Conditions préalables

Pour que tout cela ait un sens, il est nécessaire de lire le exposant d'un tour, qui vous permet d'exporter une clé de session vers un blob (une structure d'octets bien connue).On peut alors faire ce qu'on veut avec ce flux d'octets, mais il détient la clé la plus importante.

La documentation MSDN prête à confusion

Dans cet exemple particulier, j'utilise le Fournisseur cryptographique amélioré Microsoft, avec le Triple DES (CALG_3DES) algorithme.La première chose qui m'a mis dans une boucle était le fait que la longueur de la clé est répertoriée à 168 bits, avec une longueur de bloc de 64 bits.Comment la longueur de la clé peut-elle être de 168 ?Trois clés de 56 bits ?Qu'arrive-t-il à l'autre octet ?

Donc, avec ces informations, j'ai commencé à lire ailleurs comment le dernier octet est réellement la parité et, pour une raison quelconque, CryptoAPI le supprime.Est-ce vraiment le cas?Cela semble un peu fou qu'ils fassent ça, mais OK.

Consommation de clé dans .NET

En utilisant le TripleDESCryptoServiceProvider, j'ai remarqué que les remarques dans la documentation indiquaient que :

Cet algorithme prend en charge des longueurs de clé de 128 bits à 192 bits par incréments de 64 bits.

Donc, si CryptoAPI a des longueurs de clé de 168, comment puis-je l'intégrer dans .NET qui ne prend en charge que les multiples de 64 ?Par conséquent, le côté .NET de l’API prend en compte la parité, contrairement à CryptoAPI.Comme on pourrait l'imaginer... j'étais confus.

Donc, avec tout cela, j'essaie de comprendre comment reconstruire la clé côté .NET avec les informations de parité appropriées.Faisable, mais pas très amusant...restons-en là.Une fois tout ça mis en place, tout a fini par échouer avec un CAPITAL F.

Encore avec moi?Bien, parce que je viens encore de tomber de cheval.

Ampoules et feux d'artifice

Et voilà, alors que je fouille MSDN pour chaque information, je trouve un élément contradictoire dans Win32. CryptExportKey fonction.Bas et voici, je trouve cette information inestimable :

Pour toutes les permutations de clé DES qui utilisent un PLAINTEXTKEYBLOB, seule la taille complète de la clé, y compris le bit de parité, peut être exportée.Les tailles de clé suivantes sont prises en charge.

Algorithme Taille de clé prise en charge

CALG_DES 64 bits

CALG_3DES_112 128 bits

CALG_3DES 192 bits

Il exporte donc une clé multiple de 64 bits !Waouh !Maintenant, corrigeons le code côté .NET.

Ajustement du code d'importation .NET

Il est important de garder à l’esprit l’ordre des octets lors de l’importation d’un flux d’octets contenant une clé exportée sous forme de blob à partir de CryptoAPI.Les deux API n'utilisent donc pas le même ordre d'octets, car @nic-strong l'indique, il est essentiel d'inverser le tableau d'octets avant d'essayer d'utiliser la clé.A part ça, les choses fonctionnent comme prévu.Résolu simplement :

Array.Reverse( keyByteArray );

Conclusion

J'espère que cela aidera quelqu'un.J'ai passé beaucoup trop de temps à essayer de retrouver cette trace.Laissez des commentaires si vous avez d'autres questions et je peux essayer de vous aider à compléter tous les détails.

Bonne crypto !

Autres conseils

Ok, oubliez la dernière réponse que je n'arrive pas à lire :) Vous travaillez avec des clés 3Des et non des clés RSA.

J'ai travaillé sur un tas de code pour partager des clés entre .NET, CryptoAPI et openssl.J'ai trouvé ici de nombreux bons exemples de code pour effectuer les conversions clés :

http://www.jensign.com/JavaScience/cryptoutils/index.html

Il y a des éléments 3des dans certains de ces exemples, mais c'était lié à openssl -> .NET iirc.

Je viens également de revoir le code de la clé RSA et une chose que je remarque est d'utiliser Array.Reverse() sur toutes les parties clés de la clé RSA (D, DP, DQ, InverseQ, Module, P, Q) i devinez convertir endian.Je me souviens que ce n’était pas évident lorsque j’ai abordé le problème pour la première fois.

J'espère qu'une partie de cela aidera.Bonne chance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top