2010-06-29 21 views
6

Tôi đang sử dụng đoạn mã sau trong một nỗ lực để programatically phép NetworkService tài khoản để có thể sử dụng một chìa khóa:Cố gắng để thiết lập quyền trên KeyContainer trong C# là không có hiệu lực thi hành

var RSA = new RSACryptoServiceProvider(
    new CspParameters() { 
    KeyContainerName = "MyEncryptionKey", 
    Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore 
}); 

RSA.CspKeyContainerInfo.CryptoKeySecurity.AddAccessRule(
    new System.Security.AccessControl.CryptoKeyAccessRule(
    new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null), 
    CryptoKeyRights.GenericAll, 
    AccessControlType.Allow 
) 
); 

Mã này chạy mà không có lỗi, nhưng không ảnh hưởng đến quyền của vùng chứa khóa.

Tuy nhiên, bằng cách sử dụng công cụ dòng lệnh aspnet_regiis để làm điều tương tự, hoạt động hoàn hảo:

aspnet_regiis -pa "MyEncryptionKey" "NetworkService" 

Tôi đang chạy với quyền quản trị đầy đủ - nếu tôi không chạy với các quyền, sau đó một ngoại lệ là ném. Tôi cũng đang chạy với tư cách người dùng đã tạo khóa ban đầu.

Các kho chứa khóa luôn có các quy tắc truy cập sau:

S-1-5-18   -> LocalSystem 
S-1-5-32-544  -> Administrators 
S-1-5-5-0-135377 -> MyUser 

Với aspnet_regiis, SID, S-1-5-20 được thêm vào danh sách này. Tôi không thể ảnh hưởng đến nó từ mã.

Tôi đã thử tạo mã định danh bảo mật từ định dạng sid ở dạng chuỗi, cũng như sử dụng SetAccessRule thay vì AddAccessRule.

Bất kỳ ý tưởng nào thực sự ảnh hưởng đến danh sách ACL này từ mã?

Trả lời

10

Dường như bạn không gọi là Persist. Những thay đổi bạn thực hiện đối với CryptoKeySecurity không thực sự được lưu ngay lập tức. Bạn cần sử dụng một trong các phương pháp Persist(...) để thực sự lưu các thay đổi.

NativeObjectSecurity.Persist Method (String, AccessControlSections)

Có vẻ như những của API theo một cách tiếp cận khá phức tạp để sửa đổi. Trước tiên, bạn cần tạo một CspParameters, áp dụng các thay đổi cần thiết, sau đó xây dựng nhà cung cấp từ các tham số đó. Xây dựng gọi một bản cập nhật trên vùng chứa.

var params = new CspParameters 
{ 
    KeyContainerName = "MyEncryptionKey", 
    Flags = CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore  
}; 

params.CryptoKeySecurity.AddAccessRule(
    new System.Security.AccessControl.CryptoKeyAccessRule(
    new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null), 
    CryptoKeyRights.GenericAll, 
    AccessControlType.Allow 
) 
); 

var RSA = new RSACryptoServiceProvider(params); 
+0

Đáng buồn là tất cả các phương pháp Persist đều được bảo vệ. –

+0

Dường như bạn cần sửa đổi bảo mật trước khi tạo nhà cung cấp bằng cách sử dụng CspParameters. Các CspParameters, khi được truyền cho RSACryptoServiceProvider, gọi một persist. Rất kỳ lạ để xây dựng một API, nhưng theo các tài liệu, có vẻ như nó hoạt động như thế nào. Đã cập nhật câu trả lời để phản ánh. – jrista

+4

Điều đó giúp tôi đi đúng hướng. Thuộc tính CryptoKeySecurity như được sử dụng ở trên là null, do đó, ném. Bạn có thể tạo một cái mới, nhưng nó xóa sạch bất kỳ quyền nào đã tồn tại (đây là hiệu ứng thực tế đầu tiên nó có, vì vậy bây giờ tôi bị khóa khỏi kho khóa chính của mình;). Nhưng ... nếu bạn lấy khóa từ kho khóa, hãy tạo một CspParamters mới bằng cách sao chép các giá trị từ RSA.CspKeyContainerInfo (bao gồm tên và loại nhà cung cấp, tên vùng chứa và CryptoKeySecurity), sau đó bạn có thể sửa đổi, tạo một RSA khác đối tượng chính sử dụng cspparameters, và thì đấy, tất cả đã xong. các mẫu ...? –

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