2017-11-10 4 views
0

私が維持しているデータベースのテーブルに暗号化されたコードがあります。これは2012年頃なので、「常にオン」の暗号化はありません。 3列に暗号化されたデータが含まれます。EFコード暗号化されたデータを保持するプロパティを持つ最初のモデル

EFドメインをリバースエンジニアリングすると、そのテーブル用に作成されたモデルには、タイプがbyte[]のカラムのプロパティが含まれます。これは、列がvarbinaryであるため、予想されます。だから、それは次のようになります。

class Person 
{ 
    public byte[] FirstName { get; set; } // FirstName 
} 

は、FirstNameのクラスはstringの種類を持っており、それがフレームワークによって自動的に復号化し、そのようなEFマッピング/設定のいくつかの種類を行うためのエレガントな方法はありますか?私は、sqlを使ってPersonオブジェクトをインスタンス化することができますが、この処理をフレームワークにオフロードするとよいでしょう。

私は、人々が基本的にすべてのプロパティに対してSQLクエリを使用する2つのソリューションのいずれかを見てきました。 Encrypt属性でプロパティを装飾し、すべてのプロパティのプロパティを繰り返します。しかし、リスト内のすべてのオブジェクトのすべてのプロパティに対するSQLクエリでは、正確には縮尺されません。

誰もこの問題を「解決済み」していますか?

注:私はあなたがする必要がある物事を設定するつもりだこの答えでは

OPEN SYMMETRIC KEY SomeKey DECRYPTION BY CERTIFICATE SomeCertificate 

おかげ

+1

私たちは復号化されたフィールドのSQLビューを作成し、マップしました。 –

+0

@SteveGreene私は実際に自分自身でその解決策に実際に来ました。それを確認していただきありがとうございます。あなたが答えとしてそれを提出すれば、私はそれを「答え」として喜んでマークします。これを達成する唯一の方法でなければなりません。もう一度Steveに感謝します。 – onefootswill

+0

あなたが好きな場合、答えを書くことができます。 –

答えて

0

を:データを取得するには、最初に似たSQL文を送信する必要がありますEFで暗号化された列を処理するしたがって、該当する列のタイプはVARBINARY(MAX)になります。 - 復号化された列を返すビューを作成します

CREATE TABLE dbo.Person 
(
    SomeId int NOT NULL, 
    CreatedByUserId uniqueidentifier NULL, 
    CreatedUtcDate datetimeoffset(7) NULL, 
    Rowversion timestamp NULL, 
    FirstName varbinary(MAX) NULL, 
    LastName varbinary(MAX) NULL 
) 

ステップ1:あなたのテーブルには次のようになりますと言うことができます。ビューは基本的にテーブルと同じにする必要がありますが、暗号化されたデータを保持する列の場合は、復号化されたデータを返す必要があります。それは希望のようなものになります。

CREATE VIEW [dbo].[v_Person] 
AS 
SELECT [SomeId] 
     ,[CreatedByUserId] 
     ,[CreatedUtcDate] 
     ,[RowVersion] 
     ,CONVERT(NVARCHAR(50),DECRYPTBYKEY([FirstName])) [FirstName] 
     ,CONVERT(NVARCHAR(50),DECRYPTBYKEY([LastName])) [LastName] 
FROM [dbo].[Person] 

ステップ2を - 関連するプロパティタイプとしてstringとドメインモデルのPersonクラスを作成し、いないbyte[](私たちは、復号化キャストしている場所の上Viewselect文を注意してください列はNVARCHAR)。

public class Person 
{ 
    public int SomeId { get; set; } 
    public string FirstName { get; set; } // string, not binary 
    public string LastName { get; set; } // string, not binary 
    public Guid CreatedByUserId { get; set; } 
    public DateTime CreatedUtcDate { get; set; }  
    public int SomeForeignKeyId { get; set; } 
} 

ステップ3 - 私たちは、そのドメインクラスのマッピングを設定する必要があります。 (私がここで設定している解決策はEF6用ですが、EF Coreは別のマッピングファイルをまだサポートしていないので、DbContextのOnModelCreatingイベントでこれを行う必要があります)。次のようになりますドメインオブジェクトのマッピングクラスを作成します。私たちはビュー、v_Personではなく、生のテーブルにマップされた方法

public class PersonMap : EntityTypeConfiguration<Person> 
{ 
    public PersonConfiguration(string schema) 
    { 
     ToTable("v_Person", schema); // note we map to the View 
     HasKey(x => x.SomeId); 

     // ... other properties elided for brevity 

     Property(x => x.FirstName) 
      .HasColumnName(@"FirstName") 
      .HasColumnType("nvarchar") 
      .IsOptional() 
      .HasMaxLength(50); 
     Property(x => x.LastName) 
      .HasColumnName(@"LastName") 
      .HasColumnType("nvarchar") 
      .IsOptional() 
      .HasMaxLength(50); 

     // Foreign keys 
     HasRequired(a => a.LogbookEntry) 
      .WithOptional(b => b.Person) 
      .WillCascadeOnDelete(false); 

     MapToStoredProcedures(p => 
      p.Insert(i => i.HasName("Insert_Person")) 
       .Update(u => u.HasName("Update_Person")) 
       .Delete(d => d.HasName("Delete_Person"))); 

    } 
} 

注意。
MapToStoredProceduresへの呼び出しにも注意してください。これについては次に説明します。

ステップ4 - 最後に、挿入、更新、削除用のストアドプロシージャをいくつか作成します。 SaveChangesを呼び出すと、これらはEFによって呼び出され、エンティティが持つEntityStateに応じて、関連するストアドプロシージャが呼び出されます。私はすべての3を設定しませんが、Updateストアドプロシージャの例のようなものになります。

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[Update_Person] 
    @SomeId INT, 
    @CreatedByUserId UNIQUEIDENTIFIER, 
    @CreatedUtcDate DATETIME, 
    @RowVersion_Original timestamp, 
    @FirstName NVARCHAR(50), 
    @LastName NVARCHAR(50) = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @CertKey NVARCHAR(7) = 'CertKey'; 

    UPDATE PersonDetail 
     SET    
      FirstName = ENCRYPTBYKEY(KEY_GUID(@CertKey), @FirstName), 
      LastName = ENCRYPTBYKEY(KEY_GUID(@CertKey), @LastName)   
    WHERE SomeId = @SomeId 

    SELECT SomeId, RowVersion 
    FROM PersonDetail 
    WHERE SomeId = @SomeId 
END 

は、あなたがそれをより良い方法を行っている場合はコメントをお気軽に。
乾杯

関連する問題