পোস্ট
NHibernate লিসেনার (ইন্টারসেপ্টর) দিয়ে স্বচ্ছ এনক্রিপশন বাস্তবায়ন
৩ নভেম্বর, ২০১৪ • 5 মিনিট পড়া

আপনি কি কখনো ডাটাবেসে ডেটা এনক্রিপ্ট করতে হয়েছে? এই পোস্টে, আমি অন্বেষণ করব কিভাবে nHibernate লিসেনার ব্যবহার করে আপনার ডাটাবেস থেকে আসা এবং যাওয়া ডেটা এনক্রিপ্ট ও ডিক্রিপ্ট করা যায়। ক্রিপ্টোগ্রাফি আপনার অ্যাপ্লিকেশনের জন্য স্বচ্ছ হবে।
কেন আপনি এটি করতে চাইবেন? SQL Server এর পণ্যে এনক্রিপশন বিল্ট-ইন রয়েছে। এটি সত্য, কিন্তু যদি আপনি ক্লাউডে যাচ্ছেন এবং SQL Azure ব্যবহার করতে চান তাহলে আপনার কোনো ধরনের ক্রিপ্টোগ্রাফি কৌশল প্রয়োজন হবে। SQL Azure ডাটাবেস এনক্রিপশন সাপোর্ট করে না।
nHibernate লিসেনার কি? আমি একটি লিসেনারকে এমন একটি কোড হিসেবে ভাবি যা আমি nHibernate পার্সিস্টেন্স এবং ডেটা হাইড্রেশন লাইফসাইকেলের নির্দিষ্ট এক্সটেনসিবিলিটি পয়েন্টে ইনজেক্ট করতে পারি।
এই লেখার সময় nHibernate এ নিম্নলিখিত এক্সটেনসিবিলিটি পয়েন্টগুলি উপলব্ধ।
IAutoFlushEventListener
IDeleteEventListener
IDirtyCheckEventListener
IEvictEventListener
IFlushEntityEventListener
IFlushEventListener
IInitializeCollectionEventListener
ILoadEventListener
ILockEventListener
IMergeEventListener
IPersistEventListener
IPostCollectionRecreateEventListener
IPostCollectionRemoveEventListener
IPostCollectionUpdateEventListener
IPostDeleteEventListener
IPostInsertEventListener
IPostLoadEventListener
IPostUpdateEventListener
IPreCollectionRecreateEventListener
IPreCollectionRemoveEventListener
IPreCollectionUpdateEventListener
IPreDeleteEventListener
IPreInsertEventListener
IPreLoadEventListener
IPreUpdateEventListener
IRefreshEventListener
IReplicateEventListener
ISaveOrUpdateEventListener
তালিকাটি বিস্তৃত।
স্বচ্ছ ক্রিপ্টোগ্রাফি বাস্তবায়ন করতে, আমাদের ডেটা এনক্রিপ্ট এবং ডিক্রিপ্ট করার জন্য সঠিক জায়গা খুঁজে বের করতে হবে। ডেটা এনক্রিপ্ট করার জন্য আমরা IPostInsertEventListener
এবং IPostUpdateEventListener
ব্যবহার করব। এই ইভেন্টগুলির সাথে আমরা নতুন ডেটা এবং ডাটাবেসে যাওয়া আপডেট করা ডেটা ক্যাচ করব। ডিক্রিপ্ট করার জন্য, আমরা IPreLoadEventListener
ব্যবহার করব।
এই প্রদর্শনের জন্য আমরা এনক্রিপ্ট এবং ডিক্রিপ্ট করার জন্য DatabaseCryptography
ক্লাস ব্যবহার করব। ক্রিপ্টোগ্রাফি বাস্তবায়ন এই নিবন্ধের জন্য গুরুত্বপূর্ণ নয়।
IPreLoadEventListener
public class PreLoadEventListener : IPreLoadEventListener
{
readonly DatabaseCryptography _crypto = new DatabaseCryptography();
///
/// Called when [pre load].
///
///The event. public void OnPreLoad(PreLoadEvent @event)
{
_crypto.DecryptProperty(@event.Entity, @event.Persister.PropertyNames, @event.State);
}
}
IPreInsertEventListener
public class PreInsertEventListener : IPreInsertEventListener
{
readonly DatabaseCryptography _crypto = new DatabaseCryptography();
///
/// Return true if the operation should be vetoed
///
///The event. /// true if XXXX, false otherwise.
public bool OnPreInsert(PreInsertEvent @event)
{
_crypto.EncryptProperties(@event.Entity, @event.State, @event.Persister.PropertyNames);
return false;
}
}
IPreUpdateEventListener
public class PreUpdateEventListener : IPreUpdateEventListener
{
readonly DatabaseCryptography _crypto = new DatabaseCryptography();
///
/// Return true if the operation should be vetoed
///
///The event. /// true if XXXX, false otherwise.
public bool OnPreUpdate(PreUpdateEvent @event)
{
_crypto.EncryptProperties(@event.Entity, @event.State, @event.Persister.PropertyNames);
return false;
}
}
এটি লক্ষ করা গুরুত্বপূর্ণ যে IPreUpdateEventListener
এবং IPreInsertEventListener
উভয়েই অবশ্যই false রিটার্ন করবে, অন্যথায় insert/update ইভেন্ট বাতিল হয়ে যাবে।
এখন যেহেতু আমাদের লিসেনারগুলি বাস্তবায়িত হয়েছে আমাদের সেগুলি nHibernate এর সাথে রেজিস্টার করতে হবে। আমি FluentNHibernate
ব্যবহার করছি তাই আপনি যদি raw nHibernate ব্যবহার করেন তাহলে এটি ভিন্ন হবে।
SessionFactory
public class SessionFactory
{
///
/// Creates the session factory.
///
/// ISessionFactory.
public static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2012
.ConnectionString(c => c
.FromConnectionStringWithKey("DefaultConnection")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf())
.ExposeConfiguration(s =>
{
s.SetListener(ListenerType.PreUpdate, new PreUpdateEventListener());
s.SetListener(ListenerType.PreInsert, new PreInsertEventListener());
s.SetListener(ListenerType.PreLoad, new PreLoadEventListener());
})
.BuildConfiguration()
.BuildSessionFactory();
}
অ্যাপ্লিকেশন স্তরে ডেটা ডিক্রিপ্ট এবং এনক্রিপ্ট করার সময় এটি ডাটাবেসে ডেটাকে অকেজো করে তোলে। এনক্রিপ্ট করা ফিল্ডের মানগুলি পড়তে আপনাকে ডেটাকে অ্যাপ্লিকেশনে ফিরিয়ে আনতে হবে। আমরা এনক্রিপ্ট করা ফিল্ডগুলি সীমিত করতে চাই এবং আমরা শুধুমাত্র স্ট্রিং মানগুলি এনক্রিপ্ট করতে চাই। স্ট্রিং মান ছাড়া অন্য কিছু এনক্রিপ্ট করা জিনিসগুলিকে জটিল করে তোলে। এমন কিছু নেই যা বলে আমরা তারিখ এনক্রিপ্ট করতে পারি না, কিন্তু তা করলে ডাটাবেসে তারিখ ফিল্ডটিকে একটি স্ট্রিং (nvarchar বা varchar) ফিল্ড হতে হবে, এনক্রিপ্ট করা ডেটা ধরে রাখার জন্য, একবার আমরা এটি করলে আমরা ডাটাবেস থেকে তারিখ ফিল্ডে অপারেশন করার ক্ষমতা হারিয়ে ফেলি।
কোন ফিল্ডগুলি আমরা এনক্রিপ্ট এবং ডিক্রিপ্ট করতে চাই তা চিহ্নিত করতে আমি মার্কার অ্যাট্রিবিউট ব্যবহার করব।
Encrypt Attribute
public class EncryptAttribute : Attribute
{
}
Decrypted Attribute
public class DecryptAttribute : Attribute
{
}
EncryptAttribute
এবং DecryptedAttribute
কর্মে দেখতে আমরা DatabaseCryptography
ক্লাসের মধ্যে একটি উঁকি দেব।
DatabaseCryptography
public class DatabaseCryptography
{
private readonly Crypto _crypto = ObjectFactory.GetInstance();
///
/// Encrypts the properties.
///
///The entity. ///The state. ///The property names.
public void EncryptProperties(object entity, object[] state, string[] propertyNames)
{
Crypt(entity, propertyNames, s = >
_crypto.Encrypt(s),
state)
;
}
///
/// Crypts the specified entity.
///
///
///The entity. ///The state. ///The property names. ///The crypt.
private void Crypt(object entity, string[] propertyNames, Func<string, string> crypt, object[] state) where T : Attribute
{
if (entity != null)
{
var properties = entity.GetType().GetProperties();
foreach (var info in properties)
{
var attributes = info.GetCustomAttributes(typeof (T), true);
if (attributes.Any())
{
var name = info.Name;
var count = 0;
foreach (var s in propertyNames)
{
if (string.Equals(s, name, StringComparison.InvariantCultureIgnoreCase))
{
var val = Convert.ToString(state[count]);
if (!string.IsNullOrEmpty(val))
{
val = crypt(val);
state[count] = val;
}
break;
}
count++;
}
}
}
}
}
///
/// Decrypts the property.
///
///The entity. ///The state. ///The property names.
public void DecryptProperies(object entity, string[] propertyNames, object[] state)
{
Crypt(entity, propertyNames, s = >
_crypto.Decrypt(s),
state)
;
}
}
এটাই। এখন ডেটার এনক্রিপশন এবং ডিক্রিপশন অ্যাপ্লিকেশনের জন্য স্বচ্ছ হবে এবং আপনি পরবর্তী Facebook তৈরি করে আপনার আনন্দময় পথে এগিয়ে যেতে পারেন।
লেখক: চাক কনওয়ে সফটওয়্যার ইঞ্জিনিয়ারিং এবং জেনারেটিভ এআই-তে বিশেষজ্ঞ। তার সাথে সোশ্যাল মিডিয়ায় যোগাযোগ করুন: X (@chuckconway) অথবা তাকে YouTube-এ দেখুন।