Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline losko  
#1 Оставлено : 6 августа 2012 г. 16:35:21(UTC)
losko

Статус: Участник

Группы: Участники
Зарегистрирован: 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;
}
}
}









































Offline Андрей Писарев  
#2 Оставлено : 6 августа 2012 г. 19:09:30(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,752
Мужчина
Российская Федерация

Сказал «Спасибо»: 577 раз
Поблагодарили: 2307 раз в 1807 постах
В чем смысл создавать новые ветки + копировать код?

http://cryptopro.ru/foru....aspx?g=posts&t=5000

ГДЕ использование p\Invoke в static void Main(string[] args) ???

Цитата:

Crypt_Key_Prov_Info info = new Crypt_Key_Prov_Info();


и... а дальше вы за меня напишите, так?


Отредактировано пользователем 6 августа 2012 г. 19:12:45(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей Писарев  
#3 Оставлено : 7 августа 2012 г. 1:34:48(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 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)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline losko  
#4 Оставлено : 7 августа 2012 г. 12:23:24(UTC)
losko

Статус: Участник

Группы: Участники
Зарегистрирован: 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()); // криптопровайдер


  



ок?

Андрей* большое тебе человеческое СПАСИБО. Сейчас я хоть буду знать в каком направлении думать дальше. Прошу прошения за мое нубство
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.