2017-05-29 4 views
10

J'ai une ancienne fonction écrite en 2013 qui décrypte le xml crypté par un autre programme.EncryptedXml Erreur de méthode DecryptDocument après la mise à jour du framework .Net

Le code est simple, vraiment

 public static void Decrypt(XmlDocument Doc) 
    { 
     // Check the arguments. 
     if (Doc == null) 
      throw new ArgumentNullException("Doc"); 

     // Create a new EncryptedXml object. 
     EncryptedXml exml = new EncryptedXml(Doc); 

     // Decrypt the XML document. 
     exml.DecryptDocument(); 

    } 

Il a travaillé comme un charme jusqu'à récemment que certains de nos clients ont commencé à améliorer leur cadre de 4.6.2, la méthode DecryptDocument() a cessé de fonctionner. Maintenant, il lance une exception "Le groupe d'algorithmes" est invalide ". Si je supprime .net framework 4.6.2 cela fonctionne à nouveau.

L'exemple de code dans ce link va reproduire l'erreur, il va crypter avec succès puis échouer à déchiffrer. J'utilise des certificats A3, jeton pendrive. Quelqu'un at-il fait face à ce problème? il y a un travail autour de .net 4.6.2?

Edit 1:

Stacktrace:

at System.Security.Cryptography.CngAlgorithmGroup..ctor(String algorithmGroup) at System.Security.Cryptography.CngKey.get_AlgorithmGroup() at System.Security.Cryptography.RSACng..ctor(CngKey key) at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate) at System.Security.Cryptography.CngLightup.GetRSAPrivateKey(X509Certificate2 cert) at System.Security.Cryptography.Xml.EncryptedXml.DecryptEncryptedKey(EncryptedKey encryptedKey) at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri) at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument() at Criptografar.Program.Decrypt(XmlDocument Doc) in C:\Users\leoka\Documents\Visual Studio 2017\Projects\ConsoleApp4\Criptografar\Program.cs:line 152 at Criptografar.Program.Main(String[] args) in C:\Users\leoka\Documents\Visual Studio 2017\Projects\ConsoleApp4\Criptografar\Program.cs:line 83

+1

Avez-vous une pile complète? –

+0

Les clients ont-ils été complètement reconstruits? Demander au client de faire une copie du dossier bin dans le projet. Puis supprimez le dossier bin et recompilez. Je suspecte que l'erreur est due aux dépendances dans le compilateur. Le compilateur n'a aucune dépendance à la version Net, donc quand un nouveau Net est installé, une recompilation complète est requise. Le compilateur ne fera pas automatiquement une compilation complète. – jdweng

+0

@jdweng Il échoue même sur ma machine de développement, j'ai commencé un nouveau projet, collé l'exemple de code de ce [lien] (https://msdn.microsoft.com/en-us/library/ms148633 (v = vs.110) .aspx). Il n'a pas réussi à déchiffrer. –

Répondre

1

Je ne peux pas reproduire le problème moi-même - je n'ai pas le "jeton de clé USB" qui, je le suspecte, est le problème - donc c'est une conjecture. Il existe deux générations d'API cryptographiques dans Windows: the "old" one et "new generation" one, known as CNG. Maintenant, si vous regardez le source code for the CngLightup type qui apparaît à mi-chemin de votre trace de pile, en particulier la méthode DetectRsaCngSupport, vous verrez que .NET framework essaie d'utiliser l'API de nouvelle génération si possible. Ma conjecture est que le dispositif «jetrive token» ne supporte pas la nouvelle API. Vous pouvez vérifier cela en forçant l'utilisation de l'ancienne API. Malheureusement, il ne semble pas y avoir d'indicateur de configuration publique qui contrôle cela, vous devez donc recourir à des hacks basés sur la réflexion. Par exemple, vous pouvez mettre quelque chose comme ça au début de votre programme, de sorte qu'il exécute une fois, avant de tenter l'opération de déchiffrage:

var cngLightupType = typeof(EncryptedXml).Assembly.GetType("System.Security.Cryptography.CngLightup"); 
    var preferRsaCngField = cngLightupType.GetField("s_preferRsaCng", BindingFlags.Static | BindingFlags.NonPublic); 
    var getRsaPublicKeyField = cngLightupType.GetField("s_getRsaPublicKey", BindingFlags.Static | BindingFlags.NonPublic); 
    var getRsaPrivateKeyField = cngLightupType.GetField("s_getRsaPrivateKey", BindingFlags.Static | BindingFlags.NonPublic); 
    preferRsaCngField.SetValue(null, new Lazy<bool>(() => false)); 
    getRsaPublicKeyField.SetValue(null, null); 
    getRsaPrivateKeyField.SetValue(null, null); 

Prenez note qu'il est extrêmement aki, pas thread-safe, erreur la manipulation est omise, etc. Si vous vérifiez que l'utilisation du GNC est le problème, vous pouvez demander au fournisseur de jeton «clé USB» de fournir les pilotes qui travaillent avec le GNC. Ou vous pouvez vivre avec le hack ci-dessus, réécrit pour plus de sécurité.

+0

Merci beaucoup, j'ai testé et ça a marché. Je peux plonger plus profondément dans le problème maintenant que je sais ce qui allait mal. Et ce hack va m'acheter du temps pour trouver une meilleure solution, s'il y en a. –

2

Il y a quelques changements d'exécution dans .Net 4.6.2 qui affectent EncrtyptedXml - voir https://msdn.microsoft.com/en-us/library/mt670901(v=vs.110).aspx#Anchor_5

+0

Merci pour l'info, mais ce lien ne dit rien de ne pas pouvoir utiliser les certificats A3 pour le déchiffrement, avec le commentaire @silkfire j'ai découvert que même pas une instance de RSAPrivateKey je peux obtenir. Je ne pense pas que ce soit un problème avec le fabricant de jetons, puisque plusieurs clients utilisant des jetons différents signalent le même problème. En outre, il n'indique pas comment résoudre le problème. –

0

je suis tombé sur quelque chose de très similaire aujourd'hui qui s'est avéré être un bug dans .NET 4.6.2: https://github.com/Microsoft/dotnet/issues/341

Selon cette question, il y a deux solutions de contournement:

1) Mise à niveau du système d'exploitation vers Windows Server 2012R2 ou plus récent, 2) le chargement du profil de l'utilisateur .

+1

Nous vous remercions de votre suggestion. J'ai installé une machine virtuelle avec Windows Server 2012R2, j'ai appliqué toutes les mises à jour de Windows et cela ne fonctionne toujours pas avec .net framework 4.6.2. J'utilise une application de bureau, donc configurer IIS pour charger le profil utilisateur ne correspond pas. –