2014-04-08 16 views
13

Tôi đã cố gắng và không tìm ra cách tiếp cận tốt để mã hóa dữ liệu SQL với Mã khung thực thể đầu tiên. Tôi phải bắt đầu với điều này tôi đang lưu trữ trong Azure và không có quyền truy cập vào mã hóa SQL bản địa.Làm cách nào để mã hóa dữ liệu trong Mã khung thực thể đầu tiên?

Lấy một trang từ SecurEntity, tôi đã thực hiện đầy đủ một cách tiếp cận sử dụng SaveChanges và ObjectMaterialized để xử lý mã hóa/giải mã của các đối tượng, nhưng trong thử nghiệm tôi đã tìm thấy này đã được xa quá không đáng tin cậy để sử dụng.

Đây là một mẫu của một số tình hình thực hiện:

public override int SaveChanges() 
{ 
    var pendingEntities = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager 
     .GetObjectStateEntries(EntityState.Added | EntityState.Modified) 
     .Where(en => !en.IsRelationship).ToList(); 

    foreach (var entry in pendingEntities) //Encrypt all pending changes 
     EncryptEntity(entry.Entity); 

    int result = base.SaveChanges(); 

    foreach (var entry in pendingEntities) //Decrypt updated entities for continued use 
     DecryptEntity(entry.Entity); 

    return result; 
} 

void ObjectMaterialized(object sender, ObjectMaterializedEventArgs e) 
{ 
    DecryptEntity(e.Entity); 
} 

Tôi đã nhìn thấy bài viết khác mà tự mã hóa/giải mã thông qua thuộc tính thứ cấp, như vậy:

public Value { get; set; } 

[NotMapped] 
public DecryptedValue 
{ 
    get { return Decrypt(this.Value); } 
    set { this.Value = Encrypt(value); } 
} 

này sẽ chắc chắn nhất công việc, nhưng tôi thấy cách tiếp cận này là ... ít hơn lý tưởng. Khi sử dụng phương pháp này, tất cả các nhà phát triển phải lội qua tất cả các thuộc tính được mã hóa để tìm ra những thuộc tính nào họ có thể sử dụng.

Giải pháp lý tưởng nhất sẽ là để tôi có thể ghi đè việc nhận/cài đặt của từng giá trị ở cấp truy cập dữ liệu. Có cách nào để làm việc này không? Nếu không, làm thế nào tôi có thể thực hiện mã hóa dữ liệu với Entity Framework - Mã đầu tiên để nó sẽ dễ dàng để duy trì và làm việc với?

+3

Lưu ý rằng việc triển khai SecurEntity hiện tại có lỗ hổng bảo mật nghiêm trọng, có nghĩa là khóa được tạo ra từ chứng chỉ thực sự không bao giờ được sử dụng. Để khắc phục nhanh chóng và bẩn, hãy xem https://securentity.codeplex.com/workitem/7376 –

Trả lời

10

Tôi có tin vui. Sự bất ổn tôi đã trải qua với phương pháp SaveChanges/ObjectMaterialized là do thực tế rằng DetectChanges() không được gọi cho đến khi DbContext thực sự thực hiện lưu.

Tôi có thể sửa lỗi này bằng cách gọi DetectChanges() trước khi tôi kéo các bản ghi Đã thêm/Sửa đổi từ ObjectStateManager. Điều này xóa bất kỳ trạng thái đối tượng kỳ lạ đã gây ra hành vi mã hóa không phù hợp.

Mã kết quả phúc:

public override int SaveChanges() 
{ 
    var contextAdapter = ((IObjectContextAdapter)this); 

    contextAdapter.ObjectContext.DetectChanges(); 

    var pendingEntities = contextAdapter.ObjectContext.ObjectStateManager 
     .GetObjectStateEntries(EntityState.Added | EntityState.Modified) 
     .Where(en => !en.IsRelationship).ToList(); 

    foreach (var entry in pendingEntities) //Encrypt all pending changes 
     EncryptEntity(entry.Entity); 

    int result = base.SaveChanges(); 

    foreach (var entry in pendingEntities) //Decrypt updated entities for continued use 
     DecryptEntity(entry.Entity); 

    return result; 
} 

EDIT - Thêm một DataContext mẫu để xem tôi giải pháp end-to-end để mã hóa tất cả các thực thể. Lưu ý: Bạn không phải sử dụng thuộc tính tùy chỉnh để mã hóa thuộc tính. Source

+1

có cách nào để ghi đè lên tất cả các thuộc tính phương thức GET để giải mã chúng không? Tôi không muốn phải làm điều này trên một cơ sở cho mỗi đối tượng, chúng ta có thể ghi đè nó trên một mức độ toàn cầu, sau đó vòng lặp các thuộc tính và giải mã bất kỳ tài sản chuỗi? –

+0

Tôi không chắc chắn những gì bạn đang yêu cầu, nhưng nó có thể sửa đổi các thuộc tính của tất cả các đối tượng khi chúng được lưu/lấy trong EntityFramework. Đó chính xác là những gì 'EncryptEntity' và 'DecryptEntity' trong mã mẫu của tôi. Tôi sẽ thêm hai phương thức đó vào câu trả lời của tôi để tham khảo. –

+0

Bạn có thể chia sẻ phiên bản EncryptionService của mình không? Nếu không, bạn có thể cho tôi một số hướng dẫn về cách đạt được điều này không? Tôi đã thử tìm kiếm điều này nhưng chưa thành công nhiều về những thứ như nơi lưu trữ các khóa mã hóa, v.v. –

Các vấn đề liên quan