Quelle est la meilleure façon de protéger les données sensibles dans le code?
j'examinais les moyens de protéger mon code de la décomposition.
il y a plusieurs bons fils ici décrivant l'obscurcissement et l'empaquetage du code comme les moyens possibles de protéger le code. Cependant aucun d'entre eux n'est idéal, l'obfuscation ne fonctionne pas avec la réflexion lorsque la méthode de chaîne de caractères/noms de propriétés sont utilisés. Beaucoup de gens ne recommandent pas d'utiliser l'obscurcissement du tout.
j'ai donc décidé de ne pas aller avec l'un des ci-dessus. Toutefois,je avoir des parties de code où j'ai besoin d'une sorte de chiffrement, par exemple, une chaîne de connexion de base de données avec une IP, login et mot de passe est stockée à l'intérieur du code comme simple const string
, identique aux données de Compte email.
dans ASP.NET il y a une option pour déplacer les données sensibles vers un .config
le fichier et le chiffrer, mais cela nécessite la clé du serveur, c.-à-d. liée à un seul ordinateur. Je n'ai pas beaucoup lu à ce sujet, mais je suppose que quelque chose de similaire est disponible pour les applications de bureau. Mais Je besoin pour travailler sur ordinateur où l'application est installée.
et voici la question: y a-t-il des moyens d'encoder/protéger de telles données pour qu'elles ne puissent pas être lues en même temps que du code décomposé?
7 réponses
le premier conseil est jamais stockez tout ce qui est sensible dans votre code directement. Vous pouvez toujours désosser qui, n'importe comment habilement vous essayez de dissimuler.
j'ai lu des choses comme briser un mot de passe en plusieurs morceaux, les placer à différents endroits dans le code et les exécuter à travers une série de fonctions avant de finalement les utiliser... bien que cela rende les choses plus difficiles, vous pouvez toujours surveiller l'application en utilisant un débogueur et, finalement, vous serez en mesure de récupérer les informations secrètes.
si j'interprète correctement votre scénario, ce que vous avez c'est du code qui doit être déployé dans les locaux d'un client et votre code est connecté à une base de données (qui je suppose est également sous la supervision du client), se connecter à elle nécessite un mot de passe. Ce mot de passe est connu de ce client, donc essayer de le cacher au client est plutôt inutile. Ce que vous vous voulez restreindre l'accès à que le mot de passe de quelqu'un qui n'est pas censé le savoir.
Vous obtiennent généralement en mettant les informations sensibles dans un fichier séparé dans un dossier qui devrait avoir très restrictive des autorisations, que l'application et une poignée de personnes devraient avoir accès. L'application accéderait alors à l'information au besoin pendant l'exécution.
en outre crypter le fichier séparé s'avère être un problème - si vous le faites, alors il ya une clé en cause cela devrait encore une fois être sécurisé d'une manière ou d'une autre - la récursion infinie est en route :) sécuriser l'accès au fichier est souvent suffisant, mais si vous avez vraiment besoin d'être aussi sécurisé que possible, alors une solution est d'utiliser le cryptage par mot de passe pour le fichier. Mais l'idée ici n'est pas de stocker le mot de passe dans un autre endroit sur le système, mais plutôt comme information hors bande (par exemple dans une voûte physique) et entrer le mot de passe lors du démarrage de l'application. Cela, aussi, a ses problèmes: physique la présence d'une personne est nécessaire pour (re-)démarrage de l'application, et vous pouvez toujours récupérer le mot de passe de la RAM de la machine sur laquelle l'application s'exécute. Mais il est probablement le meilleur que vous pouvez faire sans matériel spécialisé.
une autre bonne alternative au cryptage basé sur le mot de passe serait de s'appuyer sur des "cavités de mot de passe" spécifiques à L'OS comme Windows' Stockage Isolé, c'est une sorte de compromis entre Ne pas crypter du tout et garder le mot de passe out-of-band.
ce n'est pas une réponse de cryptage, mais une façon de "sécuriser" cela serait de faire tous vos appels de base de données par le biais d'un service web. Vos informations de connexion seraient alors stockées sur votre serveur sécurisé et les clients passent tous les appels par là.
Rien sensibles stockées dans votre re-distribuable...
je me suis déjà attaqué à ce problème dans le passé et j'ai trouvé trois façons de le régler, mais je ne suis pas sûr qu'elles soient parfaites:
- obscurcir ou chiffrer la valeur et l'espoir pour le meilleur. Le cryptage, bien sûr, est juste un niveau supplémentaire d'obscurcissement puisque la clé doit être livrée avec le reste.
- éliminez le besoin de la clé elle-même en utilisant le cryptage à Sens Unique à la place. L'utilisation d'une clé privée pour générer une clé publique. Ceci peut être utilisé pour la validation de licence ou de mot de passe. Vous générez les licences avec la clé privée, mais la clé publique peut être utilisée pour valider. Ou vous utilisez la clé privée pour générer un mot de passe qui peut être validé, mais pas inversé en utilisant la clé publique.
- créer votre propre mécanisme de génération de clés propre au système similaire à celui utilisé par ASP.NET. Vous pouvez limiter l'effet de quelqu'un qui inverse le cryptage/l'obfuscation à l'étape 1 en générant une clé unique pour chaque installation ou site.
il y a des tonnes de méthodes, mais la réalité est que si vous voulez vraiment protéger votre code, la seule solution est d'utiliser des produits "professionnels": -) n'essayez pas de réinventer la roue. Ces produits ont normalement des options pour crypter les chaînes. Le vrai problème en est un autre: sans produit professionnel (et même avec un produit professionnel) un expert peut simplement mettre un point de rupture et regarder les paramètres passés à la méthode de la bibliothèque (par exemple celui qui ouvre les connexions). Maintenant... Si vous voulez vraiment crypter les chaînes de votre code, c'est assez facile. Mais serait-il utile? Aucun.
maintenant, juste pour que personne ne marque ceci comme "pas de réponse", je vais poster un code de cryptage/décryptage simple:
// Generate key. You do it once and save the key in the code
var encryptorForGenerateKey = Aes.Create();
encryptorForGenerateKey.BlockSize = 128;
encryptorForGenerateKey.KeySize = 128;
encryptorForGenerateKey.GenerateKey();
encryptorForGenerateKey.GenerateIV();
var key = encryptorForGenerateKey.Key;
var iv = encryptorForGenerateKey.IV;
// Encrypt: this code doesn't need to be in the program. You create a console
// program to do it
var encryptor = Aes.Create();
var encryptorTransformer = encryptorForGenerateKey.CreateEncryptor(key, iv);
string str = "Hello world";
var bytes = Encoding.UTF8.GetBytes(str);
var encrypted = encryptorTransformer.TransformFinalBlock(bytes, 0, bytes.Length);
var encryptedString = Convert.ToBase64String(encrypted);
Console.WriteLine(encryptedString);
// Decrypt: this code needs to be in the program
var decryptor = Aes.Create();
var decryptorTransformer = decryptor.CreateDecryptor(key, iv);
byte[] encrypted2 = Convert.FromBase64String(encryptedString)
var result = decryptorTransformer.TransformFinalBlock(encrypted2, 0, encrypted2.Length);
var str2 = Encoding.UTF8.GetString(result);
ce code n'est clairement pas sécurisé. N'importe qui peut décompiler le programme, ajouter un Console.WriteLine(str2)
et le recompiler.
vous pouvez bien sûr chiffrer votre chaîne de caractères avant de la compiler, mais votre code a besoin de cela en texte clair parfois si vous utilisez une simple url db ou http.
il n'y a pas de véritable protection dans ce cas: tout le monde peut écouter (breakpoint) une méthode spécifiée et quand il est appelé voir ce qui se passe sans vraiment lire votre code. Donc non, il n'y a pas de protection réelle contre cela, en utilisant aussi l'obscurcissement à un moment donné vous appellerez une méthode .NET avec cette chaîne de texte simple, et tout le monde peut le lire.
vous pouvez par exemple mettre un COM ou C++ dll pour stocker des chaînes cryptées. Une dll non gérée n'est pas décompilable, cependant, les personnes expertes peuvent bien sûr comprendre le démontage d'une dll. Et comme nous l'avons déjà dit, vous aurez parfois besoin de données claires, et à ce moment-là, il n'y a pas de protection qui puisse durer.
La seule chose que vous pouvez faire est de changer votre architecture.
Par exemple, si votre base de données est en ligne et que votre application est un client application, vous pouvez vous connecter en utilisant des services web. Ensuite, vous pouvez exposer seulement les services web que l'Utilisateur a vraiment besoin d'utiliser, il n'y a aucun risque d'écrire des requêtes sql de l'utilisateur. Ensuite, vous pouvez ajouter la logique de protection sur le serveur à la place de celle sur le client.
si tout est hors ligne, il n'y a pas grand-chose que vous puissiez faire, vous pouvez rendre la vie plus difficile en utilisant le cryptage à chaîne simple, mais il ne sera jamais une véritable protection.
comme Lucas l'a souligné dans son commentaire, si vous n'avez qu'une seule pièce, Alors quiconque décompilant votre application peut la rétro-concevoir et déchiffrer vos mots de passe de base de données.
en ce qui concerne le stockage des justificatifs d'identité, ma pratique habituelle est de toujours les stocker dans le fichier de configuration de l'application. Si j'ai besoin de le sécuriser, j'utilise une sécurisation et un cryptage. Et cela pourrait fonctionner pour n'importe quel type d'information de configuration, pas seulement des justificatifs d'identité. Il y a un très bon article sur les sécuriser les fichiers de configuration ici: cryptage des mots de passe dans une application .NET.Fichier de configuration
peut-être que vous devriez lire un peu plus sur le cryptage du web.config http://learn.iis.net/page.aspx/141/using-encryption-to-protect-passwords/
sinon il n'y a pas grand chose que vous puissiez faire. Le stockage de données sensibles dans le code n'est pas une option puisque n'importe qui avec un outil de réflecteur peut l'ouvrir et le voir. Si vous voulez que le code ou les variables soient invisibles pour tout le monde, vous devez créer un service web sur un serveur privé qui accepte les données, les transforme par sa magie et les renvoie. pour le client. De cette façon, tout en entre l'affichage et la récupération des données est gardé secret.