다음은 keypal 도구와 동일한 작업을 수행하는 샘플 코드입니다. 모든 컨테이너 (로컬 컴퓨터 용)를 열거하고 거기에서 StrongNameKeyPairs이 될 수있는 컨테이너를 가져옵니다.
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);
}
:
using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
실제를 해결하지 일반적으로 강력한 이름 키는 160 바이트 길이의 공개 키 (SHA1)가 문제가 발생했을 때 도움이되는 경우 ... 일반적으로 Attributes를 통해 지정하는 것은 더 이상 사용되지 않습니다 (V1.1 코드베이스 외부에서 볼 때 어려움을 겪을 수 있음). VS 로의 설치 관리 및 저장소 전달 CSC 작업에? (http://stackoverflow.com/a/16464894/11635) –
@RubenBartelink 흥미 롭습니다. 감사합니다. 나는이 것들에 대한 최신 정보가 거의 없기 때문에 많은 것을 생각했다. ReSharper 플러그인의 사용자가 버그를보고하고 자신의 경우 여전히 특성을 사용하고 있기 때문에 나는 관심을 보이지 않고 있습니다. 그래서 나는 그들을 "돕는"것이 얼마나 어려울 지 궁금했습니다. 그러나 그것은 더 이상 거의 사용하지 않는 것처럼 보입니다. –