2010-07-21 14 views
8

के साथ एन्क्रिप्टेड कॉलम किसी ने एन्क्रिप्टेड मानों को डीबी से इकाई फ्रेमवर्क 4 के माध्यम से खींचने का एक अच्छा तरीका निकाला है?एंटिटी फ्रेमवर्क

मुझे des_encrypt से एन्क्रिप्टेड कुछ कॉलम के साथ एक MySQL डीबी मिला है और उन मानों को जितना संभव हो सके उतना आसान प्राप्त करने में सक्षम होना चाहिए, और निश्चित रूप से, उन्हें अपडेट और डालें।

मुझे लगता है कि यह काफी अजीब है कि ईएफ में इसके लिए निर्मित समर्थन में प्रतीत नहीं होता है। यहां तक ​​कि हमारे स्वयं के निर्मित ओआरएम सिस्टम के लिए भी इसका समर्थन है। हम केवल एन्क्रिप्टेड प्रत्येक फ़ील्ड के लिए "एन्क्रिप्टेड" टिप्पणी जोड़ते हैं और ORM टूल क्वेरी में des_decrypt (कॉलम) और des_encrypt (कॉलम) जोड़ देगा।

कोई भी?

उत्तर

2

आईएमओ आपको से पहले डेटाबेस में डालने और इसे बाइनरी डेटा के रूप में स्टोर करने से पहले एन्क्रिप्ट करना चाहिए। फिर आप आसानी से byte[] ईएफ के साथ प्राप्त कर सकते हैं।

संपादित करें: यदि आप सभी des_encrypt और des_decrypt के साथ-साथ selects/inserts/deletes करने के लिए संग्रहीत प्रक्रिया का उपयोग करते हैं तो क्या होगा। फिर ईएफ अभी भी आपके लिए मैपिंग करेगा?

+0

एक अच्छा समाधान की तरह लगता है और यदि मैं एक नया डेटाबेस बनाया तो शायद मैं इसके साथ जाऊंगा। बात यह है कि डेटाबेस बहुत बड़ा है और कई परियोजनाओं द्वारा इसका उपयोग किया जाता है, इसलिए कोड पर जाने और इसे बदलने के लिए यह एक बड़ी नौकरी होगी। – Andreas

+0

@Andreas - ऊपर मेरा संपादन देखें। – TheCloudlessSky

+0

सुझाव के लिए धन्यवाद। यह वास्तव में एक अच्छा विचार की तरह लग रहा था और मैंने इसे आजमाया। दुर्भाग्यवश यदि मैं तालिका से अपने सभी डिक्रिप्ट किए गए डेटा पर LINQ क्वेरी करने में सक्षम होना चाहता हूं, तो संग्रहीत प्रक्रिया को पहले निष्पादित करना होगा। यह हमेशा के लिए लेता है क्योंकि यह 250 000+ पंक्तियों के साथ 5 कॉलम के साथ प्रत्येक को डिक्रिप्ट किया जाता है। तो ऐसा कर रहा है: context.AllMembers()। जहां (x => x.MemberId == 1) बहुत लंबा लगेगा। निश्चित रूप से मैं एक एसपी कर सकता हूं जो सदस्यीय का तर्क लेता है, लेकिन अगर मैं खोजना चाहता हूं तो क्या होगा LINQ के साथ पहला नाम? शायद मैं यहां कुछ महत्वपूर्ण याद कर रहा हूं ... – Andreas

1

आप एईएस एन्क्रिप्शन (2 रास्ता एन्क्रिप्शन) का उपयोग कर सकते हैं। जब आपको डीबी से पूछताछ करने की आवश्यकता होती है तो आप एन्क्रिप्टेड स्ट्रिंग भेज सकते हैं जो लक्ष्य मान का प्रतिनिधित्व कर सकता है।

आप इकाई को डिक्रिप्ट करने के लिए एक एक्सटेंशन बना सकते हैं।

MyTableEntitiesSet.Where(c=>c.MyField == MySeekValue.Encrypt()).First().Decrypt(); 

यह डेटाबेस क्वेरी कर सकता है।

डेटा आकार के प्रति सचेत रहें, एन्क्रिप्टेड डेटा बड़ा है ...

+4

पुराना प्रश्न और उत्तर, लेकिन केवल यह जान लें कि यदि आप ऐसा करने का प्रयास करते हैं, तो यह केवल तभी काम करेगा जब आप एक निश्चित इनिट वेक्टर का उपयोग करते हैं, जिसकी अनुशंसा नहीं की जाती है, क्योंकि यह संभवतः किसी हमलावर को डेटा के बारे में जानने की अनुमति दें। प्रत्येक एन्क्रिप्शन के साथ एक यादृच्छिक चतुर्थ का उपयोग किया जाना चाहिए, जिसका अर्थ यह होगा कि हर बार जब आप कुछ एन्क्रिप्ट करते हैं तो आपको एक अलग मूल्य मिल जाएगा। –

-3

मेरी विशिष्ट मामले में मैं एक क्रेडिट कार्ड नंबर है, जो हमेशा 16 अक्षर है एन्क्रिप्ट करने के लिए की जरूरत है; तो मैंने अभी प्राप्त करने में एक शर्त जोड़ा (अगर लंबाई! = 16 फिर डिक्रिप्ट करें) और सेट में (अगर लंबाई == 16 फिर एन्क्रिप्ट करें)। यह काम करता है और मुझे बहुत काम से बचाता है।

12

यह @TheCloudlessSky द्वारा प्रस्तावित उत्तर का कार्यान्वयन उदाहरण है। मैंने सोचा कि इससे किसी को भी मदद मिलेगी जो सोच रहा था कि इसे लागू करने के बारे में कैसे जाना है।

मैं मौजूदा डेटाबेस के साथ काम कर रहा था, इसलिए मूल मॉडल वर्ग स्वचालित रूप से मेरे लिए जेनरेट किया गया था।

स्वत: निर्मित User.cs:

namespace MyApp.Model 
{ 
    public partial class User 
    { 
     public int UserId { get; set; } 
     public byte[] SSN { get; set; } 
     ... 
    } 
} 

मैं अपने खुद के User.cs. बनाया (ध्यान दें कि यह ऑटो नामित उपयोगकर्ता.cs के समान नामस्थान में है और कोई कंपाइलर त्रुटियां नहीं थीं क्योंकि ऑटो जेनरेट किए गए User.cs को आंशिक वर्ग के रूप में घोषित किया गया था! इसके अलावा, मेरे स्वयं के User.cs उसी फ़ोल्डर में नहीं हो सकते फ़ाइल नाम संघर्ष की वजह से स्वत: जनरेट User.cs!)

namespace MyApp.Model 
{ 
    public partial class User 
    { 
     public string DecryptedSSN { get; set; } 
     ... 
    } 
} 

अब जब भी मैं अपने DbContext से उपयोगकर्ता को पुनः प्राप्त करने के लिए गए थे, मैं सभी गुण स्वत: जनरेट वर्ग के साथ-साथ लोगों में परिभाषित के रूप में परिभाषित देखेंगे मेरी उन्नत कक्षा।

यहां मेरे उपयोगकर्ता रिपोजिटरी का कार्यान्वयन है।सीएस:

namespace MyApp.Model 
{ 
    public interface IUserRepository 
    { 
     User Get(int userId); 
     ... 
    } 

    public class UserRepository : IUserRepository 
    { 
     public User GetById(int userId) 
     { 
      using (var dataContext = MyDbContext()) 
      { 
       var user = dataContext.Users.Find(u => u.UserId == userId); 
       var decryptedSSNResult = dataContext.Decrypt(u.SSN); 
       user.DecryptedSSN = decryptedSSNResult.FirstOrDefault(); 
       return user; 
      } 
     } 
    } 
} 

अब आप सोच रहे हो सकता है कि कैसे/जहाँ मैं MyDbContext.Decrypt() से मिला?

यह आपके लिए ऑटो जनरेट नहीं है। हालांकि, आप इस संग्रहीत प्रक्रिया को अपने स्वत: जेनरेट मॉडल में आयात कर सकते हैं। Context.cs फ़ाइल। (यह प्रक्रिया आधिकारिक EntityFramework आलेख में बहुत अच्छी तरह से प्रलेखित है: कैसे करें: http://msdn.microsoft.com/en-us/library/vstudio/bb896231(v=vs.100).aspx पर एक संग्रहीत प्रक्रिया (इकाई डेटा मॉडल उपकरण) आयात करें)

बस अगर आपको नहीं पता कि अंतिम परिणाम कैसा दिखना चाहिए, तो यहां है क्या स्वतः अपने Model.Context.cs में बनाया गया:

namespace MyApp.Model 
{ 
    // using statements found here 

    public partial class MyDbContext : DbContext 
    { 
     public MyDbContext() 
      : base("name = MyDbContext") 
     { } 

     public virtual ObjectResult<string> Decrypt(byte[] encryptedData) 
     { 
      var encryptedDataParameter = encryptedData != null ? 
          new ObjectParameter("encryptedData", encryptedData) : 
          new ObjectParameter("encryptedData", typeof(byte[])); 

      return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<string>("Decrypt", encryptedDataParameter); 
     } 

     // similar function for Encrypt 
    } 
} 

यह कैसे मेरे डिक्रिप्ट संग्रहित प्रक्रिया लग रहा है जैसे:

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 

प्रदर्शन विचार

अब जब मैंने आपको @TheCloudlessSky द्वारा दिए गए उत्तर का कार्यान्वयन दिखाया है, तो मैं कुछ प्रदर्शन संबंधी बिंदुओं को त्वरित रूप से हाइलाइट करना चाहता हूं।

1) प्रत्येक बार जब आप उपयोगकर्ता ऑब्जेक्ट को पुनर्प्राप्त करते हैं, तो डेटाबेस के लिए 2 ट्रिप किए जा रहे हैं। ऑब्जेक्ट को पुनर्प्राप्त करने के लिए पहली यात्रा; एसएसएन डिक्रिप्ट करने के लिए दूसरी यात्रा। यदि आप सावधान नहीं हैं तो इससे प्रदर्शन समस्याएं हो सकती हैं।

सिफारिश: ऑटो एन्क्रिप्टेड फ़ील्ड को डिक्रिप्ट न करें! ऊपर दिखाए गए मेरे उदाहरण में, जब मैं उपयोगकर्ता ऑब्जेक्ट पुनर्प्राप्त कर रहा था, तो मैंने एसएसएन को डिक्रिप्ट कर दिया। मैंने ऐसा किया था कि केवल प्रदर्शन उद्देश्यों के लिए था! खुद से पूछें कि क्या आपको वास्तव में एसएसएन की आवश्यकता है हर बार उपयोगकर्ता को पुनर्प्राप्त किया जाता है। यदि संभव हो, उत्सुक डिक्रिप्शन पर आलसी डिक्रिप्शन चुनें!

2) हालांकि मैंने यह प्रदर्शित नहीं किया है, हर बार जब आप उपयोगकर्ता ऑब्जेक्ट बनाते/अपडेट करते हैं, तो डेटाबेस में 2 ट्रिप भी किए जाएंगे। एसएसएन एन्क्रिप्ट करने के लिए पहली यात्रा; वस्तु डालने के लिए दूसरी यात्रा। यदि आप सावधान नहीं हैं तो फिर से यह प्रदर्शन समस्याओं का कारण बन सकता है।

सिफ़ारिश: इस प्रदर्शन हिट के बारे में सचेत रहें लेकिन एन्क्रिप्ट करने और एक अलग तरीके के रूप में एसएसएन के बचत प्रतिनिधि नहीं है। इसे सभी एक ऑपरेशन में रखें अन्यथा आप इसे पूरी तरह से सहेजना भूल सकते हैं। तो बनाने/अद्यतन करने की सिफारिश पुनर्प्राप्ति के विपरीत है: आलसी एन्क्रिप्शन पर उत्सुक एन्क्रिप्शन चुनें!

+0

मैं आपको प्रयास के लिए वोट देता हूं। लेकिन मैं आपके दृष्टिकोण से थोड़ा असहमत हूं। मैं नहीं चाहता कि मेरा डेटाबेस मूल्यों को डिक्रिप्ट कर दे। मैं अपने आवेदन में उस सारी जानकारी को स्टोर कर सकता हूं और डेटाबेस में दो यात्रा नहीं कर सकता। – mac10688

+0

@ mac10688 मैं डेटाबेस से कई यात्राओं के साथ जुड़े प्रदर्शन हिट पर आपसे सहमत हूं।आम तौर पर, सीयूडी संचालन के लिए समर्पित संग्रहित प्रक्रियाओं को लिखना और उन्हें इकाई ढांचे के माध्यम से मॉडल से जोड़ना एन्क्रिप्ट/डिक्रिप्ट जैसी संग्रहीत प्रक्रियाओं की तुलना में अधिक कुशल है। लेकिन मैं एप्लिकेशन के बजाय डेटाबेस द्वारा प्रबंधित कुंजी का उपयोग करके एन्क्रिप्शन/डिक्रिप्शन प्राप्त करने की एक विधि का प्रदर्शन करना चाहता था। –

+0

मैं इकाई फ्रेमवर्क द्वारा सीयूडी परिचालन प्रक्रियाओं को सीयूडी परिचालन प्रक्रियाओं से जोड़ने के लिए एक लिंक प्रदान कर रहा हूं, अगर कोई इसे प्राप्त करने के बारे में उत्सुक है: https://msdn.microsoft.com/en-us/data/jj593489। मुझे पता है कि लिंक आम तौर पर फंसे हुए हैं, लेकिन चूंकि यह एमएसडीएन इकाई फ्रेमवर्क दस्तावेज़ीकरण साइट पर है, इसलिए मुझे आशा है कि लोग इसे ध्यान में रखेंगे। –

1

आप DIY/रोल-अपनी स्वयं की एन्क्रिप्शन सुरक्षा जा सकते हैं लेकिन हर सुरक्षा विशेषज्ञ आपको never, ever, do that पर बताएगा। डेटा सुरक्षा और एन्क्रिप्शन का सबसे कठिन हिस्सा वास्तव में "एईएस" या कुछ एल्गोरिदम नहीं है। यह महत्वपूर्ण प्रबंधन है। जल्दी या बाद में, आप इस जानवर का सामना करेंगे और यह रास्ता कठिन है।

सौभाग्य से, नामक एक उपकरण है जो इसका ख्याल रखता है। वास्तव में यह इकाई फ्रेमवर्क एन्क्रिप्शन से परे चला जाता है, स्वचालित टैपर सुरक्षा, सुरक्षित कुंजी भंडारण, सुरक्षित कुंजी वितरण, कुंजी रोल ओवर, कुंजी कैशिंग, एक्सेस कंट्रोल सूचियां और भी बहुत कुछ प्रदान करता है। मुफ्त समुदाय संस्करण है और इसमें आपके ऐप में जोड़ने के लिए केवल कुछ मिनट लगते हैं।

जब इकाई की रूपरेखा के साथ एकीकृत, तो आप सिर्फ डाटा मॉडल [Secure] के साथ उनकी व्याख्या या Secure_SocialSecurityNumber की तरह कुछ करने के लिए एक संपत्ति के नाम (Secure_ महत्वपूर्ण हिस्सा है) और CipherDb बाकी का ख्याल रखता है।

उदाहरण के लिए, अपने डेटा मॉडल होगा:

public class Patient 
{ 
    public int Id {get; set;} 

    [Secure] 
    public string FullName {get; set;} 

    [Secure] 
    public string SocialSecurityNumber {get; set;} 
} 

और अपने web.config होगा

<configuration> 
    <configSections> 
    <section 
     name="crypteronConfig" 
     type="Crypteron.CrypteronConfig, CipherCore, Version=2017, Culture=neutral, PublicKeyToken=e0287981ec67bb47" 
     requirePermission="false" /> 
    </configSections> 

    <crypteronConfig> 
    <myCrypteronAccount appSecret="Get_this_from_http://my.crypteron.com" /> 
    </crypteronConfig> 
</configuration> 

यह अपने web.config सुरक्षित करने के लिए अनुशंसा की जाती है या Crypteron API कुंजी (AppSecret प्लग) प्रोग्रामिक रूप से (documentation)

आप https://github.com/crypteron/crypteron-sample-apps पर गिटहब पर नमूना ऐप्स पा सकते हैं। ।

वैसे, मुफ़्त संस्करण वाणिज्यिक प्रसाद से लाभान्वित होता है, इसलिए उपर्युक्त के अतिरिक्त, आप स्ट्रीम, फाइल, ऑब्जेक्ट्स, संदेश कतार, नोएसक्यूएल डेटाबेस इत्यादि को भी एक ही स्थान से सुरक्षित कर सकते हैं।

अस्वीकरण: मैं वहां काम करता हूं और हमारे पास एक स्वतंत्र सामुदायिक संस्करण है जो कोई भी उपयोग कर सकता है (और हम कोई पैसा नहीं कमाते हैं)। अगर आपको लगता है कि यह अच्छा है, तो हमें बताएं, अपने दोस्तों को बताएं। यदि आपके पास बजट है, तो एक वाणिज्यिक लाइसेंस प्राप्त करें। यह हमें सभी को मुफ्त संस्करण प्रदान करने में मदद करता है :)

संबंधित मुद्दे