2013-05-20 30 views
11

Tôi đang cố gắng tìm một số thông tin về cách (nếu có thể) liệt kê tất cả tên vùng chứa trong CSP tên mạnh (Nhà cung cấp dịch vụ mã hóa).Liệt kê tên vùng chứa của tên mạnh CSP

Về cơ bản, khi bạn nhập sn.exe -i key.snk MyContainerName, cặp khóa công cộng và khóa cá nhân được lưu trữ vào cái được gọi là "vùng chứa". Sau đó, trong mã của bạn, bạn có thể chỉ định tên chứa trong AssemblyKeyNameAttribute, ví dụ .:

[assembly: AssemblyKeyName("MyContainerName")] 

Điều này sẽ gây ra hội đồng sẽ được ký kết tại thời gian biên dịch.

Tôi đang cố gắng tìm hiểu xem có thể nào đó bằng cách nào đó liệt kê tất cả tên vùng chứa. Tôi đang viết một số plugin for ReSharper cung cấp mã hoàn thành cho thuộc tính InternalsVisibleTo. Tôi cũng muốn cung cấp mã hoàn thành cho thuộc tính AssemblyKeyName, nơi tôi sẽ điền trước danh sách có tên vùng chứa đã biết.

Thông tin này có thể truy cập được không?

EDIT: Từ một bình luận trên this question tại Bảo mật CNTT StackExchange, có một liên kết đến một chút util gọi KeyPal. Chạy tiện ích này với LM sẽ đổ địa phương cửa hàng trọng điểm máy:

--------- KeyPal: MACHINE store: 3 keycontainers --------- 
[0] VS_KEY_F726FDF898BC4CB8 
    Signature 1024 
[1] IIS Express Development Certificate Container 
    Exchange 1024 
    CertE: CN=localhost 
[2] MyContainerName 
    Signature 1024 
------------------------------------------------- 

đâu tôi có thể thấy rằng cả hai [0] và [2] là tên vùng chứa được hợp lệ để sử dụng với AssemblyKeyName. Tuy nhiên, có một [1] một - "IIS Express ...", mà không phải là một container hợp lệ. Làm cách nào để phân biệt chúng?

+1

Không giải quyết thực tế vấn đề, nhưng trong trường hợp nó giúp ... Bạn biết nói chung thông qua các thuộc tính không được chấp nhận (như trong bạn sẽ đấu tranh để nhìn thấy nó bên ngoài của V1.1 codebases) trong lợi của VS quản lý cài đặt vào cửa hàng và đi qua chúng vào nhiệm vụ CSC? (http://stackoverflow.com/a/16464894/11635) –

+0

@RubenBartelink Thú vị, cảm ơn. Tôi cho là nhiều, vì hầu như không có thông tin cập nhật về những thứ này. Tôi chỉ làm điều này không quan tâm, vì người dùng plugin ReSharper của tôi đã báo cáo lỗi và trong trường hợp của anh ta, họ vẫn đang sử dụng các thuộc tính. Vì vậy, tôi tự hỏi khó khăn như thế nào để "hỗ trợ" chúng. Nhưng, nó trông giống như bất cứ ai hầu như không sử dụng nó nữa. –

Trả lời

4

Đây là mã mẫu mà kinda thực hiện tương tự như công cụ bàn phím đó. Nó liệt kê tất cả các thùng chứa (đối với máy cục bộ) và từ đó có một vùng chứa có thể trở thành StrongNameKeyPairs. Thông thường, khóa tên mạnh có 160 byte có độ dài khóa công khai (SHA1):

foreach (var kc in KeyUtilities.EnumerateKeyContainers("Microsoft Strong Cryptographic Provider")) 
{ 
    CspParameters cspParams = new CspParameters(); 
    cspParams.KeyContainerName = kc; 
    cspParams.Flags = CspProviderFlags.UseMachineKeyStore; 
    using (RSACryptoServiceProvider prov = new RSACryptoServiceProvider(cspParams)) 
    { 
     if (prov.CspKeyContainerInfo.Exportable) 
     { 
      var blob = prov.ExportCspBlob(true); 
      StrongNameKeyPair kp = new StrongNameKeyPair(prov.ExportCspBlob(false)); 
      Console.WriteLine(kc + " pk length:" + kp.PublicKey.Length); 
     } 
    } 
    Console.WriteLine(); 
} 

...

public static class KeyUtilities 
{ 
    public static IList<string> EnumerateKeyContainers(string provider) 
    { 
     ProvHandle prov; 
     if (!CryptAcquireContext(out prov, null, provider, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET | CRYPT_VERIFYCONTEXT)) 
      throw new Win32Exception(Marshal.GetLastWin32Error()); 

     List<string> list = new List<string>(); 
     IntPtr data = IntPtr.Zero; 
     try 
     { 
      int flag = CRYPT_FIRST; 
      int len = 0; 
      if (!CryptGetProvParam(prov, PP_ENUMCONTAINERS, IntPtr.Zero, ref len, flag)) 
      { 
       if (Marshal.GetLastWin32Error() != ERROR_MORE_DATA) 
        throw new Win32Exception(Marshal.GetLastWin32Error()); 
      } 

      data = Marshal.AllocHGlobal(len); 
      do 
      { 
       if (!CryptGetProvParam(prov, PP_ENUMCONTAINERS, data, ref len, flag)) 
       { 
        if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS) 
         break; 

        throw new Win32Exception(Marshal.GetLastWin32Error()); 
       } 

       list.Add(Marshal.PtrToStringAnsi(data)); 
       flag = CRYPT_NEXT; 
      } 
      while (true); 
     } 
     finally 
     { 
      if (data != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(data); 
      } 

      prov.Dispose(); 
     } 
     return list; 
    } 

    private sealed class ProvHandle : SafeHandleZeroOrMinusOneIsInvalid 
    { 
     public ProvHandle() 
      : base(true) 
     { 
     } 

     protected override bool ReleaseHandle() 
     { 
      return CryptReleaseContext(handle, 0); 
     } 

     [DllImport("advapi32.dll")] 
     private static extern bool CryptReleaseContext(IntPtr hProv, int dwFlags); 

    } 

    const int PP_ENUMCONTAINERS = 2; 
    const int PROV_RSA_FULL = 1; 
    const int ERROR_MORE_DATA = 234; 
    const int ERROR_NO_MORE_ITEMS = 259; 
    const int CRYPT_FIRST = 1; 
    const int CRYPT_NEXT = 2; 
    const int CRYPT_MACHINE_KEYSET = 0x20; 
    const int CRYPT_VERIFYCONTEXT = unchecked((int)0xF0000000); 

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
    private static extern bool CryptAcquireContext(out ProvHandle phProv, string pszContainer, string pszProvider, int dwProvType, int dwFlags); 

    [DllImport("advapi32.dll", SetLastError = true)] 
    private static extern bool CryptGetProvParam(ProvHandle hProv, int dwParam, IntPtr pbData, ref int pdwDataLen, int dwFlags); 
} 

Các Namespaces sau được tham chiếu:

using Microsoft.Win32.SafeHandles; 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Reflection; 
using System.Runtime.InteropServices; 
using System.Security.Cryptography; 
+1

Điều này thật tuyệt vời, cảm ơn! Gần đây tôi đã sửa đổi plugin nhỏ của mình để đọc các tệp snk trực tiếp bằng một số utils từ Roslyn. Tôi cũng có thể kết hợp một số mã của bạn vào đó (với phân bổ phù hợp, tất nhiên!) –

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