2011-01-21 32 views
8

Tôi đã sao chép mã nguồn từ ứng dụng này sang ứng dụng khác, cả hai đều chạy trên cùng một máy. Tôi cũng đang sử dụng cùng một chuỗi cho containerName bên dưới trong cả hai ứng dụng.Đối tượng đã tồn tại trong RSACryptoServiceProvider

Điều gì đang ngăn ứng dụng mới của tôi đọc khóa đã được lưu trong ứng dụng khác? Tất cả những thứ khác đều bình đẳng, đăng nhập tài khoản người dùng, vv

 CspParameters cspParams = new CspParameters(); 
    cspParams.KeyContainerName = containerName; 
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore; 

    // Get error "object already exists" below. 
    RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); 

Trả lời

7

Bạn có cố gắng để cấp quyền truy cập vào tất cả mọi người, ví dụ, cho các tập tin trong "Documents and Settings \ All Users \ Application Data \ Microsoft \ Crypto \ RSA \ Máy Keys", vì nó mô tả ở đó:

http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/f7b9f928-a794-47f2-a5bd-9f64ca375040

+0

Có thể không áp dụng kể từ tôi chạy cùng một mã trong hai dự án khác nhau, nhưng trong cùng một tài khoản người dùng. – LamonteCristo

+0

Đó có phải là vị trí của Windows XP không? "C: \ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys" là vị trí Vista (và lên) tôi nghĩ. – granadaCoder

2

tôi chạy vào vấn đề này bởi vì dịch vụ WCF của tôi không có quyền truy cập vào keystore. Tôi lừa bóng qua vấn đề bằng cách làm theo các hướng dẫn để cấp cho người dùng ASPNET đọc truy cập mà tôi tìm thấy ở đây: http://msdn.microsoft.com/en-us/library/2w117ede.aspx#Y898

5

Một giải pháp khác là để thiết lập quyền truy cập vào tất cả mọi người theo mã:

CspParameters cspParams; 
cspParams = new CspParameters(PROVIDER_RSA_FULL); 
cspParams.KeyContainerName = CONTAINER_NAME; 
cspParams.Flags = CspProviderFlags.UseMachineKeyStore; 
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider"; 

CryptoKeyAccessRule rule = new CryptoKeyAccessRule("everyone", CryptoKeyRights.FullControl, AccessControlType.Allow); 

cspParams.CryptoKeySecurity = new CryptoKeySecurity(); 
cspParams.CryptoKeySecurity.SetAccessRule(rule); 
+0

Chỉ cần chạy vào vấn đề này. Sử dụng dòng lệnh 'aspnet_regiis -pa" SampleKeys "" NT AUTHORITY \ NETWORK SERVICE "' không hoạt động, nhưng giải pháp của bạn đã thực hiện công việc. Cảm ơn rất nhiều! –

+1

Thay vì "tất cả mọi người", tôi đã phải vượt qua 'SecurityIdentifier mới (WellKnownSidType.WorldSid, null)'. Tôi cho rằng nó không hoạt động vì người dùng "mọi người" được bản địa hóa sang ngôn ngữ của tôi trên máy của tôi. – Tom

+2

Giống như FYI cho bất kỳ ai tìm thấy điều này, để sử dụng 'CryptoKeyAccessRule', bạn phải làm' bằng cách sử dụng System.Security.AccessControl', và đối với 'SecurityIdentifier' mới và' WellKnownSidType', đó là 'using System.Security.Principal'. VS 2015 là tốt về việc đề xuất sửa lỗi cho không gian tên, nhưng bất kỳ ai sử dụng phiên bản trước đó, những người có thể không biết các không gian tên rất tốt, có thể khó tìm ra những gì cần nhập. Hãy cho chúng tôi biết hội đồng của bạn khi bạn nhập những thứ nằm ngoài mặc định !!! – vapcguy

0

Gần đây tôi đã chạy vào vấn đề này với nhiều trang IIS được triển khai trên một máy chủ (Windows 2008 R2). Môi trường của chúng tôi có mỗi trang web chạy trên các hồ bơi ứng dụng khác nhau, nhưng trong một số trường hợp, các hồ bơi đó có thể được chỉ định cùng một danh tính.

Ứng dụng của chúng tôi tạo khóa nếu không tồn tại và đặt nó vào một vùng chứa có tên dựa trên danh tính hiện tại. Trang web được triển khai đầu tiên luôn hoạt động, nhưng nếu chúng tôi triển khai một trang web khác vào một nhóm ứng dụng khác có cùng một danh tính thì trang web thứ hai sẽ không thành công.

Chỉ ra rằng khi khóa được lưu trữ, Windows sẽ cấp quyền truy cập đầy đủ cho người dùng "IIS APPPOOL \ AppPoolName" và không phải là danh tính mà chúng tôi đã gán cho nhóm.

Vì vậy, giải pháp của chúng tôi là cung cấp cho các thùng chứa điều khoản rõ ràng với bản sắc hiện nay (điều này cũng tương tự như câu trả lời @ Webmixer, sự khác biệt duy nhất là trong CryptoKeyAccessRule):

CspParameters cspParams; 
cspParams = new CspParameters(PROVIDER_RSA_FULL); 
cspParams.KeyContainerName = CONTAINER_NAME; 
cspParams.Flags = CspProviderFlags.UseMachineKeyStore; 
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider"; 

CryptoKeyAccessRule rule = new CryptoKeyAccessRule(System.Security.Principal.WindowsIdentity.GetCurrent(), CryptoKeyRights.FullControl, AccessControlType.Allow); 

cspParams.CryptoKeySecurity = new CryptoKeySecurity(); 
cspParams.CryptoKeySecurity.SetAccessRule(rule); 
+0

Tôi nhận được 'Không thể chuyển đổi từ 'System.Security.Principal.WindowsIdentity' thành 'System.Security.Principal.IdentityReference'' khi tôi thử chèn nó, như được viết. Có lẽ cần 'SecurityIdentifier mới (System.Security.Principal.WindowsIdentity.GetCurrent(). ToString())'? – vapcguy

+0

Không chắc chắn. Tôi đoán điều gì đó có thể đã thay đổi trong vài năm qua. Chúng tôi đã gỡ bỏ mã trên một số thời gian trước đây. –

+0

Đã thử nó, nó biên dịch, nhưng có lỗi 'Hệ thống.ArgumentException: Giá trị không hợp lệ', vì vậy nó không thích nó. Tôi không nghĩ rằng đó là cú pháp, mặc dù - Tôi đã nhận được điều tương tự bằng cách sử dụng gợi ý của Tom về câu trả lời của Webmixer ('SecurityIdentifier mới (WellKnownSidType.WorldSid, null)'). Nếu tôi sử dụng câu trả lời của Webmixer trực tiếp, để sử dụng '" mọi người "', tôi nhận được 'CryptographicException: Object đã tồn tại'. – vapcguy

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