.Net Core Üzerinde İşaretli Kolonların Şifrelenerek Kaydedilmesi

Selamlar,

Bu makalede, istenen bir tabloya ait kolonun işaretlenerek, kaydedilme sırasında şifrelenmesini, .Net Core Entity Framework üzerinde inceleyeceğiz.

Öncelikle bu projede DB First kullanılmıştır. Ama istenir ise aynı işlem, CodeFirst bir yapı için de uygulanabilir.

User.cs: Aşağıda görüldüğü gibi bir User tablosu vardır. Bu örnekte Gsm alanı, güvenlik nedeni ile kaydedilirken, geriye dönülebilir Encrypted bir şekilde SQL DB’de saklanacaktır.

Şimdi Users sınıfına bağlı, partial bir başka Users class’ı oluşturalım. Yeni oluşturulan bu sınıfı BaseEntitiy adında bir sınıftan, Inherit alalım. Böylece DB’den generate edilen classlarda, ortak bir değişikliğe gidilmek istendiğinde, BaseEntity class’ı üzerinde yapılacak bir ekleme, yeterli olacaktır.

PartialEntities/User(1):

Core/BaseEntity: Örneğin aşağıdaki BaseEntity sınıfında, her entity’nin ortak CreatedTime alanı bulunmaktadır. [NotMapped] olarak işaretlenerek, DB ile herhangi bir eşleşme yapılmaması sağlanmıştır.

PartialEntities/CryptoData: Şifrelenecek property veya propertylere konacak Crypto işareti, aşağıdaki gibi tanımlanır.

Not: Herhangi bir classın var olan bir kolonuna, PartialClass’ında doğrudan işaretlemeye çalışılır ise, böyle bir kolon var hatası alınır. Bunun için MetaData tanımlanıp, ilgili kolonun üstünde işaretlenmesi gerekmektedir.

PartialEntities/UserMetaData: Users tablosunda var olan bir kolonu işaretlemek için, aşağıdaki gibi bir MetaData’nın tanımlanması gerekmektedir.

PartialEntities/User(2): Aşağıda görüldüğü gibi, ilgili Users Model, “UserMetaData” ile işaretlenir. Böylece Users ==> Gsm kolonu [CryptoData] şeklinde işaretlenmiş olunur.

Şimdi sıra geldi global bir Repository yaratıp, ilgili işaretleme ile gelen kolonları şifrelemeye.

Repository/IRepository: GeneralRepository katmanın inherit edileceği interfacedir. Örnek amaçlı sadece “Insert()” methodu zorlanmıştır.

Repository/GeneralRepository : IRepository’den türeyen bu sınıfdaki “Insert()” methodu, projedeki tüm servislerden, herhangi bir entity’e kaydedilme anında çağrılan methoddur. Kısaca dağıtık bir mimaride, her yerden çağrılan DB ile iletişimi sağlayan katmandır.

  • _context : DB katmanıdır.
  • _entities : Entity, yani DB’deki bir tablodur.
  • IEncryption : Bir sonraki adımda tanımlanacak olan, şifreleme işleminin yapıldığı sınıftır.
  • “public GeneralRepository(NorthwindContext context, IEncryption encryption)” : Dependency injection ile context ve encryption sınıfları sisteme alınmıştır.
  • “Insert(T entity)” : BaseEntity’den türeyen tüm entityleri paramtere olarak alan kaydetme işleminin yapıldığı methoddur.
    • “System.ComponentModel.DataAnnotations.MetadataTypeAttribute[] metadataTypes = entity.GetType().GetCustomAttributes(true).OfType<System.ComponentModel.DataAnnotations.MetadataTypeAttribute>().ToArray()” : Method üzerinde tanımlı tüm attributeler, bu kod ile “metadataTypes[]” dizisine atanır.
    • “foreach (System.ComponentModel.DataAnnotations.MetadataTypeAttribute metadata in metadataTypes)” : Metadata listesi içinde gezilir.
      • “foreach (System.Reflection.PropertyInfo pi in properties)” : Her metadata içindeki, propertyler gezilir.
        • if (Attribute.IsDefined(pi, typeof(DB.PartialEntites.CryptoData)))” : Eğer property tipi “CryptoData” ise, değeri şifrelenir.
          • “_context.Entry(entity).Property(pi.Name).CurrentValue = “: İlgili property’nin değeri alınır.
          • “_encryption.EncryptText(_context.Entry(entity).Property(pi.Name).CurrentValue.ToString())” : Şifrelenerek tekrar kendisine atanır.
  • ” _entities.Add(entity); _context.SaveChanges()” : Tüm kayıtlar DB’ye, entity yardımı ile kaydedilir.

Core/Security/IEncryption : Encryption sınıfında kullanılacak methodlar, IEncryption interface’inde aşağıdaki gibi tanımlanır.

Core/Security/Encryption : Güvenlik amaçlı işaretlenen kolonlar, “Encryption” sınıfındaki “EncryptText()” methodu kullanılarak, şifrelenir ve DB’ye kaydedilir. Aynı şekilde “DecryptText()” methodu kullanılarak, şifreli kolonların gerçek değerlerine ulaşılır.

Geldik bir makalenin daha sonuna . Bu makalede istenen bir kolon için yapılan işaretleme ile, içeriğinin şifrelenerek kaydedilmesi sağlanmıştır. Burada önemli olan, [CryptoData] ile işaretlenen tüm kolonların şifrelenerek DB’ye kaydedilmesidir. Böylece herhangi bir DBContext’deki, istenen bir kolonun, sadece işaretlenerek Repository katmanında işaret tipine göre istenen işlemin yapılabileceğini hep beraber gördük.

Yeni bir makalede görüşmek üzere hepinize hoşçakalın.

Source:

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

4 Cevaplar

  1. Selçuk dedi ki:

    Selam hocam elinize sağlık,

    Peki bu şifreli alanlarda arama yapmak istersek nasıl yapacağız?

    • borsoft dedi ki:

      Selamlar ve teşekkürler,

      Sql’de yaparsan, bir tane decrypt function’ı yazman gerekiyor. Sonra where & like koşulunda şifreli kolonu, bu function() içinde yazman gerekiyor.
      Kod tarafında çözümü için d,e linq ile aynı işlemi yapman lazım ama bu sefer sql function yerine decrypt eden C# methodu() çağırman gerekiyor.

      İyi çalışmalar.

      • Selçuk dedi ki:

        Yanıtınız için teşekkürler.

        Performans açısından bir yavaşlık olmaz mı?
        Mesela 1M kayıt içerisinde arama yaparken

  2. direncan dedi ki:

    Selamlar,
    Hocam Ef Core da bulunan value conversion özelliğini kullanmamanızın özel bi sebebi varmı. Bu özelliğin bu konuda çok daha efektif olduğunu düşünüyorum. Hem linq sorguları esnasındada otomatik çalışıyor. Kod içerisinde çalışan yazılımcının encrypt decrypt işleminden haberi olmadan çalışmasına imkan tanıyor. Cevabınızın belki projeyi Entity Framework bağımlılığından kurtarmak için olabileceğini düşünüyorum. Görüşünüz nedir ? Paylaşım için teşekkürler

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir