10
votes

Colonnes cryptées avec cadre d'entité

Quelqu'un a inscrit un bon moyen de tirer des valeurs cryptées de la DB via Framework 4?

J'ai reçu un dB mysql avec certaines colonnes cryptées avec Des_encrypt et devez pouvoir obtenir ces valeurs aussi simples que possible, et bien sûr, mettre à jour et les insérer.

Je pense que c'est assez étrange qu'il ne semble pas être dans le soutien construit pour cela dans EF. Même notre propre système orm construit a un soutien à cela. Nous allons simplement ajouter un commentaire "chiffré" pour chaque champ chiffré crypté et l'outil ORM ajoutera Des_decrypt (colonne) et Des_encrypt (colonne) dans les requêtes.

Quelqu'un?


0 commentaires

6 Réponses :


2
votes

imo Vous devriez crypter avant la mettre dans la base de données et la stocker en tant que données binaires. Ensuite, vous pouvez facilement obtenir le octet [] avec ef.

EDIT: Et si vous utilisez une procédure stockée pour effectuer tous les Des_encrypt et aussi bien que le Sélectionne / inserts / supprime pour tu. Ensuite, ef fera toujours la cartographie pour vous?


4 commentaires

On dirait une bonne solution et j'irais probablement que si j'ai créé une nouvelle base de données. La chose est que la base de données est assez grande et est utilisée par des tonnes de projets afin que ce soit un travail énorme pour passer au-dessus du code et changer cela.


Merci pour la suggestion. Cela ressemblait à une très bonne idée et je l'ai essayé. Malheureusement, si je veux être capable de faire des requêtes Linq sur toutes mes données déchiffrées de la table, la procédure stockée doit d'abord exécuter. Cela prend pour toujours car il est plus de 250 000 lignes avec 5 colonnes chacune pour être déchiffrée. Ce faisant cela: contexte.Allmember (). Où (x => x.memberid == 1) prendra trop de temps. Bien sûr, je pouvais faire un SP qui prend un argument de MemberID, mais si je veux rechercher par exemple. Prénom avec Linq? Peut-être que je manque quelque chose d'important ici ...


@Andreas - de ce que je comprends ... MemberId est crypté? Vous n'avez-vous besoin que de déchiffrer des colonnes cryptées (comme un mot de passe ... Même si vous devriez utiliser un hasch à sens unique)? Si Michaid est pas crypté, vous n'avez pas besoin de le déchiffrer pour faire un "SELECT". Quelqu'un d'autre utilise-t-il cette table? Pourquoi ne vous déchiffrez-vous pas tout et créez une nouvelle table pour les données non cryptées?


Non, tout sauf que le membre est crypté (c'est la clé primaire). Nous décrypte des choses comme numéro de sécurité sociale, noms et adresses, car il s'agit de données sensibles pour nous. Le mot de passe est haché, donc aucun problème là-bas. Cette table est utilisée beaucoup, mais nous ne voulons vraiment pas une autre version qui est déchiffrée depuis que cela fonctionnerait contre la Thea idée d'avoir les choses cryptées. Désolé pour ma réponse tardive, vacances ... :)



2
votes

Vous pouvez utiliser le cryptage AES (cryptage à 2 voies). Lorsque vous devez interroger le DB, vous pouvez envoyer la chaîne cryptée pouvant représenter la valeur cible.

Vous pouvez créer une extension pour déchiffrer l'entité. xxx

Ceci peut faire une requête de base de données.

Soyez conscient de la taille des données, les données cryptées sont plus grandes ...


1 commentaires

Vieille question et réponse, mais soyez juste conscient que si vous essayez de le faire, cela ne fonctionnera que si vous utilisez un vecteur d'initie fixe, qui n'est pas recommandé, car cela permettrait potentiellement à un attaquant d'apprendre sur les données. Un IV aléatoire avec chaque cryptage doit être utilisé, ce qui signifierait que vous obtiendriez une valeur différente chaque fois que vous cryptez quelque chose.



-7
votes

Dans mon cas spécifique, je devrais chiffrer un numéro de carte de crédit, qui est toujours de 16 caractères; Donc, je viens d'ajouter une condition dans l'obtention (si la longueur! = 16 puis déchiffrer) et dans l'ensemble (si lenght == 16, chiffrer) de la propriété. Cela fonctionne et évitait beaucoup de travail.


0 commentaires

15
votes

Ceci est un exemple de mise en œuvre de la réponse proposée par @thecloudlesssky. Je pensais que cela aidera quiconque se demandait comment faire la mise en œuvre.

Je travaillais avec une base de données existante, la classe modèle de base a donc été générée automatiquement pour moi. P>

Utilisateur généré automatiquement .cs: ​​ p> xxx pré>

J'ai créé mon propre utilisateur.ca (Remarque Il est dans la même espace de noms que l'utilisateur généré automatiquement.cs et il n'y avait pas d'erreur de compilateur car l'utilisateur généré automatiquement a été déclaré comme classe partielle em>! Aussi, mon propre utilisateur.CS ne peut pas être Dans le même dossier que l'utilisateur généré automatiquement.CS en raison du conflit de nom de fichier!) p> xxx pré>

Maintenant, chaque fois que je devais récupérer l'utilisateur de mon dbcontext, je verrai toutes les propriétés définies dans la classe générée automatiquement ainsi que celles définies dans ma classe améliorée. P>

Voici une implémentation de mes UserRepository.cs: p>

CREATE PROCEDURE decrypt
    @encryptedData VARBINARY(8000)
AS
BEGIN
    OPEN SYMMETRIC KEY xxx_Key DECRYPTION BY CERTIFICATE xxx_Cert;

    SELECT CAST(DECRYPTIONBYKEY(@encryptedData) AS NVARCHAR(MAX)) AS data;

    CLOSE ALL SYMMETRIC KEYS;
END;
GO


5 commentaires

Je vous donne un vote pour effort. Mais je suis en désaccord avec votre approche un peu. Je ne veux pas que ma base de données soit déchiffrer des valeurs. Je peux stocker toutes ces informations dans ma demande et ne pas avoir à faire deux voyages à la base de données.


@ Mac10688 Je suis d'accord avec vous sur le coup de performance associé à plusieurs voyages à la base de données. En général, écrire des procédures stockées dédiées pour les opérations CUD et les relier au modèle via un cadre d'entité est plus efficace que d'avoir des procédures stockées telles que chiffrer / déchiffrer. Mais je voulais démontrer une méthode d'obtention de cryptage / déchiffrement à l'aide des touches gérés par la base de données au lieu de l'application.


Je fournis un lien avec la manière de connecter les procédures de CUD stockées aux opérations CUD par le cadre d'entité au cas où une personne est curieuse sur la manière de y parvenir: msdn.microsoft.com/en-us/data/jj593489 . Je sais que les liens sont généralement fronçons les sourcils, mais comme celui-ci se situe au site de la documentation de la MSDN Entity Framework, j'espère que les gens ne l'dérangeront pas.


Excellent informatif utile détaillé et utile, y compris les liens de la réponse et de la commentaires! Merci beaucoup!


J'aime cette solution car la clé est réellement stockée dans la base de données. Cependant, y a-t-il un avantage de le faire? Je veux dire, est-il vraiment préférable de stocker la clé dans la base de données au lieu d'entrer dans l'application? Je ne peux que voir un inconvénient (par exemple, faire un aller-retour à la base de données). S'il y a un avantage, je changerai ma demande pour utiliser cette méthode comme j'aime vraiment l'idée que la clé est à l'intérieur de la base de données.



2
votes

Vous pouvez aller le bricolage / roll-votre propre sécurité de chiffrement, mais chaque expert de sécurité vous dira de jamais, jamais, n'est-ce que . La partie la plus difficile de la sécurité et du cryptage des données n'est en réalité pas "AES" ou de certains algorithmes. C'est la gestion clé. Tôt ou tard, vous ferez face à cette bête et c'est way plus difficile.

Heureusement, il y a un outil appelé Crypteron Cipherdb qui prend en charge cela. En fait, il va au-delà du cryptage de la structure d'entité, fournissant également une protection automatique de sabotage, un stockage de clé sécurisé, une distribution de clé sécurisée, des rouleaux de clé de clé, une mise en cache de clé, des listes de contrôle d'accès et plus encore. Il y a une édition communautaire gratuite et cela ne prend que quelques minutes à ajouter à votre application.

Lors de l'intégration de la structure d'entité, vous annotez simplement le modèle de données avec [ Secure] ou nommer une propriété à quelque chose comme Secure_SocialSecurityNumber (le Secure _ est la partie clé) et Cipherdb prend soin du reste.

Par exemple, votre modèle de données serait: xxx

et votre web.config serait xxx

Il est recommandé de Sécurisez votre web.config ou branchez la touche API Crypteron (Appsecret) Programmativement ( Documentation )

Vous pouvez trouver les exemples d'applications sur github à https: // github .Com / Crypteron / Crypteron-Sample-Apps . .

D'ailleurs, l'édition gratuite bénéficie des offres commerciales. En plus de ce qui précède, vous pouvez également sécuriser les flux, les fichiers, les objets, les files d'attente de messages, les bases de données NOSQL, etc., du tout d'un endroit.

Clause de non-responsabilité : Je travaille là-bas et nous avons une édition communautaire gratuite que tout le monde peut utiliser (et nous ne faisons pas d'argent). Si vous pensez que c'est cool, dites-nous, dites-nous à vos amis. Si vous avez un budget, obtenez une licence commerciale. Cela nous aide à proposer une édition gratuite à tous :)


0 commentaires

2
votes

Pour ceux d'entre vous googler cette question et à la recherche d'un moyen simple de déchiffrer une seule colonne / rangée (pas une table / classe entière), à ​​l'aide d'un cryptage symétrique et d'EF, vous pouvez faire celle-ci de deux (simples) façons.

premier chemin; Créez une procédure stockée qui fait votre décryptage: p> xxx pré>

... puis appelez cette procédure stockée directement dans le code, récupérant le résultat sous forme de chaîne: p>

 using (var context = new YourDatabaseContext())
        {       
            using (var dbContextTransaction = context.Database.BeginTransaction())
            {
                try
                {
                    var sql = String.Format("OPEN SYMMETRIC KEY {0} DECRYPTION BY CERTIFICATE {1}", KeyName, CertName);
                    context.Database.ExecuteSqlCommand(sql);

                    sql = String.Format("SELECT CONVERT(varchar, DecryptByKey(Encrypted_Password)) FROM Application_Credentials WHERE User_Name = '{0}'", UserNameToDecryptCredsFor);
                    var result = context.Database.SqlQuery<string>(sql).FirstOrDefault();

                    sql = String.Format("CLOSE SYMMETRIC KEY {0}", KeyName);
                    context.Database.ExecuteSqlCommand(sql);
                }
                catch (Exception exp)
                {
                    var x = exp.ToString(); //do something with exception
                }
            }
        }


1 commentaires

Vous avez écrit que ceci est pour une seule colonne / rangée mais pas pour une table / classe complète. Comment devrais-je aller à ce sujet si j'envoie / décréter tout ou la plupart des colonnes dans une table?