Статус: Участник
Группы: Участники
Зарегистрирован: 31.07.2012(UTC) Сообщений: 13
|
Доброго всем дня, пишу программу на C#. Очень очень нужна ваша помощь. Сколько не бьюсь ничего не получается. Мне уже приходилось создавать на этом форуме несколько тем по одной и той же проблеме.Суть проблемы вкратце:есть некий сертификат в хранилище MY текущего пользователя, этому сертификату соответствует закрытый ключ, находящийся в контейнере в реестре системы. Мне нужно вывести в консоль имя контейнера с этим сертификатом и ссылку на хранилище этого контейнера. Чтобы в консоли отображалось примерно следующее:
REGYSTRY\\Имя контейнера.
Многие мне посоветовали вызвать CertGetCertificateContextProperty через PInvoke //C параметрами: //PCCERT_CONTEXT pCertContext == X509Certificate2.Handle //DWORD dwPropId == CRYPT_KEY_PROV_INFO Вроде вызвать удалось, но не совсем успешно. Посмотрите пожалуйста что еще в коде пропущено, может есть что-то лишнее. Почему результат не выводится в консоль. Помогите плиз using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Permissions; using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Runtime.InteropServices;
namespace ConsoleApplication1 { class Crypto { [StructLayout(LayoutKind.Sequential)] public struct Crypt_Key_Prov_Info { public string pwszContainerName; public string pwszProvName; public Int32 dwProvType; public Int32 dwFlags; public Int32 cProvParam; public IntPtr rgProvParam; public Int32 dwKeySpec; }
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool CertGetCertificateContextProperty(
IntPtr pCertContext, uint dwPropId, IntPtr pvData, ref uint pcbData);
static void Main(string[] args) { var keyStore = new X509Store("MY", StoreLocation.CurrentUser); keyStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);
Crypt_Key_Prov_Info info = new Crypt_Key_Prov_Info();
var cert = keyStore.Certificates.Count;
{ Console.WriteLine("В хранилище текущего пользователя сертификатов: {0}", cert); }
int kol = 0;
List<X509Certificate> list = new List<X509Certificate>();
foreach (var c in keyStore.Certificates) {
kol += c.HasPrivateKey ? 1 : 0; // если свойство HasPrivateKey равно true, то к kol прибавляется единица, иначе прибавляется нуль
if (c.HasPrivateKey == true) {
list.Add(c); // выводим список всех сертификатов с закрытым ключом
}
} Console.WriteLine("Количество сертификатов с закрытым ключом: {0}", kol.ToString());
foreach (var item in list) { Console.WriteLine(item.ToString()); } Console.ReadKey();
} public RSACryptoServiceProvider RSACryptoServiceProviderFromCertContext (IntPtr pCertContext) { // Determine the size of the buffer that you need to allocate. uint cbData = 0; bool fStatus = CertGetCertificateContextProperty( pCertContext.ToInt32(), CERT_KEY_PROV_INFO_PROP_ID, (IntPtr)0, ref cbData); if (!fStatus) { Console.WriteLine("CertGetCertificateContextProperty failed: " + Marshal.GetLastWin32Error().ToString()); // Get the CERT_KEY_PROV_HANDLE_PROP_ID value and the HCRYPTPROV value. cbData = 4; IntPtr pCryptKeyProvInfo = Marshal.AllocHGlobal(new IntPtr(cbData)); fStatus = CertGetCertificateContextProperty(pCertContext.ToInt32(),CERT_KEY_PROV_INFO_PROP_ID, pCryptKeyProvInfo, ref cbData); if (!fStatus) { Console.WriteLine("CertGetCertificateContextProperty failed: " + Marshal.GetLastWin32Error().ToString()); } return null; } if (cbData != 0) { // Allocate an unmanaged buffer to store the CRYPT_KEY_PROV_INFO structure. IntPtr pCryptKeyProvInfo = Marshal.AllocHGlobal((int)cbData); // Get the CRYPT_KEY_PROV_INFO structure. fStatus = CertGetCertificateContextProperty(pCertContext.ToInt32(),CERT_KEY_PROV_INFO_PROP_ID, pCryptKeyProvInfo, ref cbData); if (!fStatus) { Console.WriteLine("CertGetCertificateContextProperty failed: " + Marshal.GetLastWin32Error().ToString()); Marshal.FreeHGlobal(pCryptKeyProvInfo); } else { // Build a CspParameters object with the provider type, the provider name, // and the container name from the CRYPT_KEY_PROV_INFO structure. // The pointer to the container name is the first DWORD in the CRYPT_KEY_PROV_INFO // structure. The pointer to the provider name is the second DWORD. // The provider type is the third DWORD. try { CspParameters CspParams = new CspParameters(Marshal.ReadInt32((IntPtr)((int)pCryptKeyProvInfo + 8)), Marshal.PtrToStringUni((IntPtr)Marshal.ReadInt32((IntPtr)((int)pCryptKeyProvInfo + 4))), Marshal.PtrToStringUni((IntPtr)Marshal.ReadInt32(pCryptKeyProvInfo))); // // Free the unmanaged CRYPT_KEY_PROV_INFO buffer. // Marshal.FreeHGlobal(pCryptKeyProvInfo); return new RSACryptoServiceProvider(CspParams); } catch(Exception ex) { Console.WriteLine(ex.Message); } } } return null; } } }
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,752   Сказал «Спасибо»: 577 раз Поблагодарили: 2307 раз в 1807 постах
|
|
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,752   Сказал «Спасибо»: 577 раз Поблагодарили: 2307 раз в 1807 постах
|
Код:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CRYPT_KEY_PROV_INFO
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszContainerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszProvName;
public uint dwProvType;
public uint dwFlags;
public uint cProvParam;
public IntPtr rgProvParam;
public uint dwKeySpec;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CRYPTOAPI_BLOB
{
public uint cbData;
public IntPtr pbData;
}
[DllImport("crypt32.dll")]
public static extern bool CertGetCertificateContextProperty(IntPtr pCertContext,
uint dwPropId, IntPtr pvData, ref uint pcbData);
public static CRYPT_KEY_PROV_INFO GetCertificateContextProperty(X509Certificate2 certificate)
{
try
{
IntPtr certhandle = certificate.Handle;
uint pcbData = 0;
if (CertGetCertificateContextProperty(certhandle, 2, IntPtr.Zero, ref pcbData))
{
IntPtr memoryChunk = Marshal.AllocHGlobal((int)pcbData);
try
{
if (CertGetCertificateContextProperty(certhandle, 2, memoryChunk,
ref pcbData))
{
CRYPT_KEY_PROV_INFO context =
(CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(memoryChunk,
typeof(CRYPT_KEY_PROV_INFO));
return context;
}
else
{
throw new Exception("сбой :( !");
}
}
finally
{
Marshal.FreeHGlobal(memoryChunk);
}
}
}
finally
{
//
}
throw new Exception("сбой :( Context Property");
}
использование: Код:
X509Certificate2 MyCertificate = .....
CRYPT_KEY_PROV_INFO Info = GetCertificateContextProperty(MyCertificate );
MessageBox.Show(Info .pwszContainerName.ToString()); // контейнер
MessageBox.Show(Info.pwszProvName.ToString()); // криптопровайдер
ок?Отредактировано пользователем 7 августа 2012 г. 1:58:27(UTC)
| Причина: Не указана |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 31.07.2012(UTC) Сообщений: 13
|
Андрей * написал: Код:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CRYPT_KEY_PROV_INFO
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszContainerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszProvName;
public uint dwProvType;
public uint dwFlags;
public uint cProvParam;
public IntPtr rgProvParam;
public uint dwKeySpec;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CRYPTOAPI_BLOB
{
public uint cbData;
public IntPtr pbData;
}
[DllImport("crypt32.dll")]
public static extern bool CertGetCertificateContextProperty(IntPtr pCertContext,
uint dwPropId, IntPtr pvData, ref uint pcbData);
public static CRYPT_KEY_PROV_INFO GetCertificateContextProperty(X509Certificate2 certificate)
{
try
{
IntPtr certhandle = certificate.Handle;
uint pcbData = 0;
if (CertGetCertificateContextProperty(certhandle, 2, IntPtr.Zero, ref pcbData))
{
IntPtr memoryChunk = Marshal.AllocHGlobal((int)pcbData);
try
{
if (CertGetCertificateContextProperty(certhandle, 2, memoryChunk,
ref pcbData))
{
CRYPT_KEY_PROV_INFO context =
(CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure(memoryChunk,
typeof(CRYPT_KEY_PROV_INFO));
return context;
}
else
{
throw new Exception("сбой :( !");
}
}
finally
{
Marshal.FreeHGlobal(memoryChunk);
}
}
}
finally
{
//
}
throw new Exception("сбой :( Context Property");
}
использование: Код:
X509Certificate2 MyCertificate = .....
CRYPT_KEY_PROV_INFO Info = GetCertificateContextProperty(MyCertificate );
MessageBox.Show(Info .pwszContainerName.ToString()); // контейнер
MessageBox.Show(Info.pwszProvName.ToString()); // криптопровайдер
ок? Андрей* большое тебе человеческое СПАСИБО. Сейчас я хоть буду знать в каком направлении думать дальше. Прошу прошения за мое нубство
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close