Quelle est la meilleure façon de protéger les données sensibles dans le code?
J'étais en examinant les moyens de protéger mon code de la décompilation.
Il y a plusieurs bonnes discussions ici de décrire l'obfuscation de code et d'emballage que les moyens de protéger le code. Cependant, aucun d'entre eux est idéal, l'obfuscation ne fonctionne pas avec la réflexion lorsque la méthode de chaîne/les noms des propriétés sont utilisées. Beaucoup de gens ne recommandons pas d'utiliser l'obfuscation à tous.
Donc je suis actuellement a décidé de ne pas aller avec ceux-ci. Cependant, j'ai des parties de code où j'ai besoin d'une sorte de cryptage, par exemple, une base de données de la chaîne de connexion avec une adresse IP, login et mot de passe est stocké à l'intérieur du code aussi simple const string
, même que le compte de messagerie de données.
Dans ASP.NET il y a une option pour déplacer les données sensibles à une .config
fichier et de le chiffrer, mais qui nécessite la clé du serveur, c'est à dire lié à un seul ordinateur. Je n'ai pas lu beaucoup à ce sujet, mais je suppose que quelque chose de similaire est disponible pour les applications de bureau. Mais j'ai besoin de ce travail sur tout ordinateur où l'application est installée.
Et voici la question: il y a des moyens de codage/la protection de ces données de sorte qu'il ne peut pas être lu en parallèle avec le code decompile?
- Le problème avec ce que vous décrivez, c'est que même si vous chiffrer ce que vous distribuez, vous devez distribuer la clé de déchiffrement avec elle pour que le code puisse le déchiffrer. Pouvez-vous ne pas externaliser les informations d'identification et de chaîne de connexion, puis demandez à vos utilisateurs de s'inscrire individuellement (chacun de faire ses propres informations d'identification)?
- Question demande pour de meilleures pratiques de mise en œuvre d'une mauvaise pratique (pensez à séparer les données de la logique à la place).
Vous devez vous connecter pour publier un commentaire.
Premier conseil est de jamais stocker des données sensibles dans votre code directement. Vous pouvez toujours désosser qui, n'importe comment habilement vous essayez de dissimuler cela.
J'ai lu à propos de choses comme casser un mot de passe en plusieurs morceaux, en les plaçant à différents endroits dans le code et de les exécuter à travers une série de fonctions avant finalement de les utiliser... même si cela rend les choses plus difficiles, vous pouvez toujours surveiller l'application à l'aide d'un débogueur et, finalement, vous serez en mesure de récupérer les informations secrètes.
Si j'interprète votre scénario correctement, ce que vous avez est le code qui est à être déployé à certains locaux du client et votre code est connecté à une base de données (qui, je suppose, est également sous le client de la surveillance), la connexion nécessite un mot de passe. Ce mot de passe est connu pour le client, et donc essayer de masquer le client est plutôt inutile. Ce que vous ne veulent, c'est de restreindre l'accès à ce 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 serait alors accéder à l'information en cas de besoin au cours de l'exécution.
En outre le chiffrement du fichier distinct s'avère être un problème si vous le faites, alors il est une clé impliqué qu'une fois aurait à être sécurisé en quelque sorte - une récursion infinie est sur son chemin 🙂 la Sécurisation de 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 un chiffrement par mot de passe pour le fichier. Mais l'idée ici est de ne pas stocker le mot de passe dans encore un autre emplacement sur le système, mais plutôt à l'extérieur de la bande (par exemple, dans un coffre-fort physique) et en entrant le mot de passe lors du démarrage de l'application. Cela, aussi, a ses problèmes: la présence physique 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 à chiffrement par mot de passe serait de s'appuyer sur les OS "mot de passe voûtes", tels que Windows Le Stockage Isolé, c'est une sorte de compromis entre le fait de ne pas chiffrer à tous et garder le mot de passe out-of-band.
Ce n'est pas un cryptage de réponse, mais un moyen de "sécuriser" ce serait de faire tous vos appels de base de données via un service web. Vos informations d'identification de connexion serait alors stocké sur votre serveur sécurisé, et les clients passent tous les appels par là.
Rien sensibles stockées dans votre re-distribuable à tous...
J'ai abordé ce problème dans le passé et à venir avec trois manières d'aborder le problème, mais je ne suis pas sûr que n'importe quel d'entre eux sont parfaits:
Il ya 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 "professionnels" de produits 🙂 ne pas essayer de réinventer la roue. Ces produits ont normalement des options à chiffrer des chaînes. Le vrai problème est autre: sans un produit professionnel (et même AVEC un produit professionnel) un expert peut simplement mettre un point d'arrêt et de regarder les paramètres passés à la méthode de bibliothèque (par exemple celui qui ouvre les connexions). Maintenant... Si vraiment vous voulez vraiment pour chiffrer les cordes de votre code, c'est assez facile. Mais serait-il utile? No.
Maintenant, juste pour que personne ne marque de cette "non pas comme une réponse", je vais poster un peu simple de chiffrement/déchiffrement code:
Ce code n'est pas sécurisé. N'importe qui peut décompiler le programme, ajouter un
Console.WriteLine(str2)
et le recompiler.const string
à l'intérieur le programme avec la clé de chiffrement. Ensuite, le programme contient également le code de décryptage. Donc si je vais décompiler le programme .NET Reflector je vais voir la clé et le déchiffrement logique, c'est à dire inutile. Est-ce exact?Bien sûr, vous pouvez crypter votre texte avant de le compiler, mais votre code besoin en texte brut, parfois, si vous êtes en utilisant un simple db ou une url http.
Il n'y a pas une réelle protection dans ce cas: tout le monde peut écouter (point d'arrêt) à une méthode déterminée et lorsqu'il est appelé à voir ce qu'il se passe sans vraiment la lecture de votre code.
Donc non, il n'y a pas une réelle protection contre ce, également à l'aide de dissimulation à un certain point, vous appelez certains .Méthode NETTE avec ce texte en clair de la chaîne, et tout le monde peut le lire.
Vous pouvez par exemple mettre un COM ou C++ dll pour stocker des chaînes cryptées.
Un non géré dll n'est pas decompilable, cependant, des personnes expertes peut bien sûr comprendre le démontage d'une dll. Et comme l'a dit avant, parfois, vous aurez besoin de la plaine de données, et à ce moment, il n'y a pas de protection, qui peut 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 une application client, vous pouvez vous connecter à l'aide de services web.
Ensuite, vous pouvez exposer uniquement les services web que l'utilisateur vraiment besoin de l'utiliser, il n'y a pas de risque de l'utilisateur de l'écriture de requêtes sql.
Vous pouvez ensuite ajouter de la protection de la logique sur le serveur plutôt que sur le client.
Si tout est hors ligne, il n'ya pas beaucoup que vous pouvez faire, vous pouvez rendre la vie plus difficile à l'aide de simple chaîne de cryptage, mais il ne sera jamais une vraie protection.
Comme Lucas l'a souligné dans son commentaire, si vous avez un seul morceau, alors n'importe qui décompilation votre application peut rétro-conception et déchiffrer les données de votre base de mots de passe.
Sur le stockage des informations d'identification, ma pratique habituelle est de toujours stocker dans le fichier de configuration d'application. Si j'ai besoin de la protéger, j'utilise un SecureString et certains de chiffrement. Et cela pourrait fonctionner pour tout type de configuration d'informations, non seulement des informations d'identification. Il y a un très bon article sur la sécurisation des fichiers de configuration ici: Chiffrement des mots de passe dans une .NET application.Fichier de configuration
Peut-être vous devriez lire un peu plus sur le chiffrement sur le web.config http://learn.iis.net/page.aspx/141/using-encryption-to-protect-passwords/
Sinon il n'y a pas beaucoup que vous pouvez faire. Le stockage de données sensibles dans le code n'est pas une option puisque n'importe qui avec un réflecteur outil peut l'ouvrir et de le voir. Si vous voulez le code ou les variables pour être invisible pour tout le monde, vous devez créer un webservice sur un serveur privé qui accepte les données, il se transforme par le biais de la magie et la renvoie au client. De cette façon, tout en entre l'affichage et la récupération des données est gardé secret.
accepts data, transforms it through it's magic and returns it to the client
n'est pas une solution. Le trafic réseau peut être reniflée ou avec des désassembleurs code en cours d'exécution peut être fixé.