Форум: "Начинающим";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];
ВнизКак узнать имя сертификта в контейнере (дискета) через CryptoAPI? Найти похожие ветки
← →
ANB © (2006-08-01 10:58) [0]Использую Крипто Про.
Провайдер проинициализирован, имя контейнера вытащил.
Просмотрел MSDN, ничего подходящего не увидел, но винда это как то делает.
Цель проста - узнать имя сертификата на дискете - носителе закрытого ключа.
← →
ANB © (2006-08-01 16:45) [1]упс. Никто не работал с Крипто АПИ ?
Значится, смог я подключиться к нужному ключу (сертификату) и вытащить его хендл. А чего дальше делать - не знаю.
← →
ANB © (2006-08-02 10:14) [2]Ну, типа примерно вот так получилось.
Константы ошибок и процедуру проверки результата не привожу - при желании кому нужно сам напишет.
class function CryptoPro.GetCertNameFromCurrentContainer() : String;
var l : Cardinal;
CryptProv : HCRYPTPROV;
UserKey : HCRYPTKEY;
ProvName : String;
ProvType : Cardinal;
Container : String;
Cert_Info : String;
Cert_Context : PCCERT_CONTEXT;
TypePara : Cardinal;
Cert_Name : String;
begin
{
// Достать имя и тип первого провайдера
// Оставляю этот закомментаренный блок на случай, если понадобится узнать имя и тип провайдера
R := CryptEnumProviders(0, nil, 0, ProvType, nil, l);
if not R then begin ShowMessage("Ошибка узнавания длинны имени провайдера"); exit; end;
SetLength(ProvName, l);
R := CryptEnumProviders(0, nil, 0, ProvType, PChar(ProvName), l);
if not R then begin ShowMessage("Ошибка узнавания имени провайдера"); exit; end;
SetLength(ProvName, l - 1);
ShowMessage("Провайдер " + IntToStr(ProvType) + " [" + ProvName + "]");
AddToLogText("Тип = " + IntToStr(ProvType) + " Имя = [" + ProvName + "]");
AddToLogText("Имя (Hex) = [" + StringToHex(ProvName) + "]");
}
ProvType := 75;
ProvName := "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider";
CryptProv := 0;
try
try
CheckError(CryptAcquireContext(CryptProv, nil, PChar(ProvName),
ProvType, CRYPT_VERIFYCONTEXT));
except
on E : Exception do begin
raise AddExceptionHeaderFooter(E, CryptoPro_Err_Prov_Connect, "", [ProvName]);
end;
end;
// Узнаем имя контейнера
// Размер
l := 0;
try
CheckError(CryptGetProvParam(CryptProv, PP_ENUMCONTAINERS, nil, l, CRYPT_FIRST));
except
on E : Exception do begin
raise AddExceptionHeader(E, CryptoPro_Err_Get_Container_Name_Len);
end;
end;
SetLength(Container, l);
// Собственно имя
try
CheckError(CryptGetProvParam(CryptProv, PP_ENUMCONTAINERS, PByte(PChar(Container)), l, CRYPT_FIRST));
except
on E : Exception do begin
raise AddExceptionHeader(E, CryptoPro_Err_Get_Container_Name_Len);
end;
end;
finally
if (CryptProv <> 0)
then CryptReleaseContext(CryptProv, 0);
end;
// Переподключимся к конкретному контейнеру
CryptProv := 0;
try
try
CheckError(CryptAcquireContext(CryptProv, PChar(Container), PChar(ProvName),
ProvType, 0));
except
on E : Exception do begin
raise AddExceptionHeaderFooter(E, CryptoPro_Err_Prov_Container_Connect, "", [ProvName, Container]);
end;
end;
try
CheckError(CryptGetUserKey(CryptProv, AT_KEYEXCHANGE, UserKey));
except
on E : Exception do begin
raise AddExceptionHeader(E, CryptoPro_Err_Get_Key);
end;
end;
try
CheckError(CryptGetKeyParam(UserKey, KP_CERTIFICATE, nil, l, 0));
except
on E : Exception do begin
raise AddExceptionHeader(E, CryptoPro_Err_Get_Cert_Len);
end;
end;
SetLength(Cert_Info, l);
try
CheckError(CryptGetKeyParam(UserKey, KP_CERTIFICATE, PByte(PChar(Cert_Info)), l, 0));
except
on E : Exception do begin
raise AddExceptionHeader(E, CryptoPro_Err_Get_Cert);
end;
end;
Cert_Context := nil;
try
Cert_Context := CertCreateCertificateContext(X509_ASN_ENCODING, PByte(PChar(Cert_Info)), l);
if (Cert_Context = nil) then begin
raise Exception.Create(CryptoPro_Err_CreateCertificateContext);
end;
l := 0;
l := CertGetNameString(Cert_Context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, @TypePara, nil, l);
if (l <= 0) then begin
raise Exception.Create(CryptoPro_Err_Get_Cert_Name_Len);
end;
SetLength(Cert_Name, l);
l := CertGetNameString(Cert_Context, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, @TypePara, PChar(Cert_Name), l);
if (l <= 0) then begin
raise Exception.Create(CryptoPro_Err_Get_Cert_Name);
end;
SetLength(Cert_Name, l - 1);
Result := Cert_Name;
finally
CertFreeCertificateContext(Cert_Context);
end;
finally
if (CryptProv <> 0)
then CryptReleaseContext(CryptProv, 0);
end;
end;
← →
Reindeer Moss Eater © (2006-08-02 10:59) [3]У сертификата нет имени.
Скажи что хочешь узнать.
← →
Reindeer Moss Eater © (2006-08-02 11:29) [4]Если имеешь валидный контекст сертификата, то значит у тебя есть например указатель на блоб с сабджектом
pCertContext^.pCertInfo^.Subject
Далее применяешь к этому блобу CertNameToStrA (CertNameToStrW) и получаешь имя владельца в чистом виде
Если нужен издатель, то идешь сюда
pCertContext^.pCertInfo^.Issuer. Там указатель на тот же самый CERT_NAME_BLOB
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.046 c