2009-10-01 8 views
0

J'ai cette fonction que j'utilise pour déchiffrer des valeurs qui fonctionnent bien sur ma machine dev. Mais lorsqu'il est exécuté en production sur un autre serveur - donne ce message d'erreur exact:C# RSA Decryption issue

Le système ne peut pas trouver le fichier spécifié.

Voici la fonction:

public static string Decrypt(string stringToDecrypt, string key) 
    { 
     string result = null; 

     if (string.IsNullOrEmpty(stringToDecrypt)) 
     { 
      throw new ArgumentException("An empty string value cannot be encrypted."); 
     } 

     if (string.IsNullOrEmpty(key)) 
     { 
      throw new ArgumentException("Cannot decrypt using an empty key. Please supply a decryption key."); 
     } 

     try 
     { 
      System.Security.Cryptography.CspParameters cspp = new System.Security.Cryptography.CspParameters(); 
      cspp.KeyContainerName = key; 

      System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(cspp); 
      rsa.PersistKeyInCsp = true; 

      string[] decryptArray = stringToDecrypt.Split(new string[] { "-" }, StringSplitOptions.None); 
      byte[] decryptByteArray = Array.ConvertAll<string, byte>(decryptArray, (s => Convert.ToByte(byte.Parse(s, System.Globalization.NumberStyles.HexNumber)))); 


      byte[] bytes = rsa.Decrypt(decryptByteArray, true); 

      result = System.Text.UTF8Encoding.UTF8.GetString(bytes); 

     } 
     finally 
     { 
      // no need for further processing 
     } 

     return result; 
    } 

Mise à jour

Les gars, je l'origine allé cette route parce que, après des heures et des heures de recherche je suis arrivé une réponse sur StackOverflow, que cette méthode de cryptage/le décryptage fonctionne uniquement sur des chaînes et pas besoin d'importer/exporter des clés.

Alors ... Maintenant, il me manque un fichier clé? Comment est-ce possible que je n'ai même pas créé un fichier clé.

+0

Quel est le but de la clause "finally" vide? –

+0

Avez-vous installé la clé dans le même conteneur de clés sur la nouvelle machine? Les erreurs de chiffrement dans .NET peuvent être quelque peu trompeuses, mais il semble qu'il ne trouve pas le conteneur de clé que vous avez spécifié. –

+0

@Rob, puisque je n'ai pas généré ce fichier clé, où puis-je le trouver? –

Répondre

2

Si vous devez copier la clé d'une machine à une autre vous allez devoir exporter à partir du conteneur clé. Nous avons constaté que les méthodes rsaCryptoServiceProvider.ImportCspBlob et ExportCspBlob fonctionnent bien pour cela; vous obtenez un seul tableau d'octets que vous pouvez ensuite Convert.ToBase64String et Convert.FromBase64String.

Bien sûr, il doit s'agir d'une clé exportable (ou mieux encore, exporter uniquement la clé publique qui est la façon dont PKC est censée être faite, donc une extrémité a la clé privée et l'autre seulement la clé publique). Une clé non exportable peut uniquement exporter sa clé publique. Une fois que le système fonctionne, vous pouvez créer une nouvelle clé non exportable dans laquelle vous avez besoin de la clé privée et exporter la clé publique pour la transférer là où elle doit être cryptée pour ce destinataire unique.

En outre, vous devez vous assurer de Dispose le fournisseur de chiffrement lorsque vous avez terminé (apparemment Clear() n'est pas assez bon). Il est bon d'utiliser une instruction using pour ce faire, si vous l'utilisez dans une portée locale, ou vous pouvez le faire dans votre bloc finally. Notez qu'il implémente IDisposable explicitement, donc vous devez le lancer à IDisposable quelque peu maladroitement pour le faire dans une déclaration séparée. Une instruction using gère le casting lui-même, donc c'est plus facile.

+1

Le déchiffrement nécessite la clé * privée *. La clé privée doit déjà être validée, vous ne pouvez pas provisionner la clé privée 'juste à temps'. Où serait installée la clé privée * de *? Quelle est la sécurité de ce magasin de clés, comment est protégé? De plus, à moins d'écrire un outil de gestion de clés explicite, vous n'avez jamais besoin d'isntall et de supprimer des clés dans le code, il existe des outils pour cela. –

+0

De toute évidence, vous devez savoir quelle est la fin et générer la clé privée à la fin de la procédure de déchiffrement (et peut-être une clé privée différente à l'autre extrémité). Mais vous devez obtenir la clé publique correspondante à d'autres endroits. Une façon de le faire (que nous utilisons) pour l'exporter vous-même. Les outils de gestion des clés en seraient un autre (que je n'ai pas utilisé). Laquelle est appropriée dépend de facteurs du scénario qui n'ont pas été mentionnés à l'origine. –

1

Utilisez FileMon de Sysinternals.com pour voir quel est le fichier qu'il recherche?

Ma conjecture est que cspp.KeyContainerName = key; est la ligne pertinente.

+0

+1 pour une bonne idée, mais fileMon n'existe plus, il a été remplacé par l'explorateur de processus, vraiment compliqué à comprendre, et je n'ai pas vraiment le temps juste cette minute. –

2

Notez que vous n'utilisez pas le paramètre key en tant que chiffre mais en tant que nom pour un conteneur. Cela dépend de la fonction de cryptage ayant stocké la clé plus tôt. Ne convient pas au transfert de données cryptées entre ordinateurs. Sauf si vous transférez les clés aussi.

+0

où puis-je trouver cette clé? –

+0

Je ne suis pas familier avec cette API. Mais reculons un peu, avec cette approche vous n'obtenez aucun des avantages de RSA mais vous obtenez les inconvénients (longueur limite, lent). Vous pouvez utiliser un cryptage symétrique. –

0

Eh bien, avez-vous installé la clé dans le conteneur nommé key dans le fournisseur de chiffrement sur le serveur? Voir How to: Use the X.509 Certificate Management Tools. Par ailleurs, si vous êtes en mesure de décrypter sur votre machine quelque chose qui devrait être une clé privée seulement sur le serveur, cette clé est déjà compromise. Vous devriez changer vos clés dès que possible.

Après votre mise à jour

cryptographie RSA est basée sur la clé assymétrique. Vous crypter avec la clé publique, les décrypots de destination avec la clé privée. Les clés sont provisionnées à l'avance, la destination de votre génère ou obtient une paire de clés et conserve la partie privée pour lui-même et annonce la partie publique pour les autres. Habituellement, les clés sont empaquetées en tant que certificats X509 car elles utilisent toute l'infrastructure de confiance autour des certificats (signatures, autorités de confiance, objectif du certificat, etc.). Dans ce cas, la destination du message doit demander un certificat à des fins de cryptage à une autorité de confiance (par exemple Verisign), etc. Ou utiliser un certificat auto-signé (makecert.exe) et établir la confiance par certaines méthodes hors bande (par ex. un appel téléphonique pour valider le hash du certificat ou IssuerName/SerialNumber).

RSa cryptographie est très loin de «juste des chaînes». Plus proche de 'just strings' est la cryptographie à clé symétrique (AES, DES, XDES, RC4) où votre application a une clé secrète utilisée pour crypter et décrypter.

Maintenant, à moins que vous savez vraiment ce que vous faites, de la cryptographie orienter clairement, utilisez un désactiver le protocole étagère comme SSL/TLS (en ligne) ou S-MIME (hors ligne). Mieux encore, utilisez certaines infrastructures comme CryptoStream ou ProtectedData. Ne créez pas encore un pseudo-cryptage basé sur les conseils de newsgroup de personnes que vous n'avez jamais rencontrées ...

+0

Jetez un oeil à CryptoStream, toujours coincé avec le même problème fondamental qui me rend fou, il va travailler localement, mais quand je porte le code en production ... il va se casser. –

+0

Votre problème n'est pas le cryptage/décryptage, est la gestion des clés. Vous devez établir clairement pour votre produit comment les clés doivent être provisionnées et utilisées. Ensuite, vous saurez dans votre code quelle clé utiliser pour crypter et le décryptage fonctionnera sur la cible prévue. Notez que sur Windows, les magasins de clés sont spécifiques à la machine (disponible uniquement aux administrateurs, donc Vista LUA requiert l'administrateur RunAs) et spécifiques à l'utilisateur. –

0

Un problème peut être que l'objet RSA tente de créer CryptoContainer dans le profil utilisateur.
Vous pouvez essayer d'ajouter ceci:

rsa.UseMachineKeyStore = true;