2011-11-17 39 views
5

Câu hỏi liên quan đến Lazarus hoặc Delphi. Có cách nào để truy cập chương trình chứng chỉ Root Certificate Authorities đáng tin cậy trong Windows hay không. Tôi biết có công cụ dựa trên GUI trong Windows được gọi là 'mmc.exe', nhưng tôi cần truy cập các tệp chứng chỉ (như .crt hoặc .cer hoặc .pem, v.v.) bằng cú pháp Object Pascal. Bất cứ ai có thể giúp tôi với điều đó?Tôi làm cách nào để truy cập vào chứng chỉ của cơ quan chứng chỉ gốc Windows bằng Delphi?

Trả lời

5

Như các lựa chọn thay thế, có CAPICOM mà bạn có thể chỉ cần nhập dưới dạng thư viện kiểu ActiveX, nhưng cũng có Windows cũ là Cryptography API.

Ví dụ: đây là dự án thử nghiệm rất cũ của tôi (Gần đây tôi chưa thử nghiệm). Bạn sẽ cần các đơn vị WinCrypt hoặc JwaWinCrypt với dịch API có liên quan mà nên có sẵn trên JEDI:

program lstore; 

{$APPTYPE CONSOLE} 

uses 
    Windows, 
    SysUtils, 
    WinCrypt; 

var 
    StoreName: array[0..255] of Char; 
    hStore: HCERTSTORE; 
    CertContext: PCertContext; 
    CertPropId: DWORD; 
    Data: array[0..511] of Char; 
    DataLen: DWORD; 
    i: Integer; 

procedure DisplayCertContext(Cert: PCertContext); 
var 
    CertName: array[0..255] of Char; 
begin 
    if CertGetNameString(CertContext, CERT_NAME_EMAIL_TYPE, 0, nil, 
    CertName, 256) = 0 then 
    RaiseLastWin32Error; 
    Writeln('Subject CERT_NAME_EMAIL_TYPE: ', CertName); 
    if CertGetNameString(CertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, 
    CertName, 256) = 0 then 
    RaiseLastWin32Error; 
    Writeln('Subject CERT_NAME_SIMPLE_DISPLAY_TYPE: ', CertName); 
    if CertGetNameString(CertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, nil, 
    CertName, 256) = 0 then 
    RaiseLastWin32Error; 
    Writeln('Subject CERT_NAME_FRIENDLY_DISPLAY_TYPE: ', CertName); 

    if CertGetNameString(CertContext, CERT_NAME_EMAIL_TYPE, CERT_NAME_ISSUER_FLAG, nil, 
    CertName, 256) = 0 then 
    RaiseLastWin32Error; 
    Writeln('Issuer CERT_NAME_EMAIL_TYPE: ', CertName); 
    if CertGetNameString(CertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, nil, 
    CertName, 256) = 0 then 
    RaiseLastWin32Error; 
    Writeln('Issuer CERT_NAME_SIMPLE_DISPLAY_TYPE: ', CertName); 
    if CertGetNameString(CertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, nil, 
    CertName, 256) = 0 then 
    RaiseLastWin32Error; 
    Writeln('Issuer CERT_NAME_FRIENDLY_DISPLAY_TYPE: ', CertName); 
end; 

begin 
    try 
    Write('Enter name of store to be listed: '); 
    Readln(StoreName); 
    hStore := CertOpenSystemStore(0, StoreName); 
    if hStore = nil then 
     RaiseLastWin32Error; 
    try 
     CertContext := CertEnumCertificatesInStore(hStore, nil); 
     while CertContext <> nil do 
     begin 
     DisplayCertContext(CertContext); 
     CertPropId := CertEnumCertificateContextProperties(CertContext, 0); 
     while CertPropId <> 0 do 
     begin 
      DataLen := 512; 
    //  Writeln(Format('CertPropId: %d', [CertPropId])); 
      case CertPropId of 
      CERT_KEY_PROV_HANDLE_PROP_ID: 
      begin 
      CertGetCertificateContextProperty(CertContext, CertPropId, 
       @Data[0], DataLen); 
      Writeln(Format('KEY_PROV_HANDLE: $%.8x', [PDWORD(@Data[0])^])); 
      end; 
      CERT_KEY_PROV_INFO_PROP_ID: 
      begin 
      CertGetCertificateContextProperty(CertContext, CertPropId, 
       @Data[0], DataLen); 
      with PCryptKeyProvInfo(@Data[0])^ do 
      begin 
       Writeln(Format('pwszContainerName = %s', [pwszContainerName])); 
       Writeln(Format('pwszProvName = %s', [pwszProvName])); 
       Writeln(Format('dwFlags = %d', [dwFlags])); 
       Writeln(Format('cProvParams = %d', [cProvParams])); 
       //Writeln(Format('rgProvParam', [rgProvParam])); 
       Writeln(Format('dwKeySpec = %d', [dwKeySpec])); 
      end; 
      Writeln(Format('KEY_PROV_INFO: %d', [@Data[0]])); 
      end; 
      CERT_FRIENDLY_NAME_PROP_ID: 
      begin 
      CertGetCertificateContextProperty(CertContext, CertPropId, 
       @Data[0], DataLen); 
      Writeln(Format('FRIENDLY_NAME: %s', [PChar(@Data[0])])); 
      end; 
      CERT_KEY_IDENTIFIER_PROP_ID: 
      begin 
      CertGetCertificateContextProperty(CertContext, CertPropId, 
       @Data[0], DataLen); 
      Write('KEY_IDENTIFIER: '); 
      for i := 1 to DataLen do 
       Write(Format('%.2x ', [PBYTE(@Data[i - 1])^])); 
      Writeln; 
      end; 
      CERT_SHA1_HASH_PROP_ID: 
      begin 
      CertGetCertificateContextProperty(CertContext, CertPropId, 
       @Data[0], DataLen); 
      Write('SHA1_HASH: '); 
      for i := 1 to DataLen do 
       Write(Format('%.2x ', [PBYTE(@Data[i - 1])^])); 
      Writeln; 
      end; 
      CERT_MD5_HASH_PROP_ID: 
      begin 
      CertGetCertificateContextProperty(CertContext, CertPropId, 
       @Data[0], DataLen); 
      Write('MD5_HASH: '); 
      for i := 1 to DataLen do 
       Write(Format('%.2x ', [PBYTE(@Data[i - 1])^])); 
      Writeln; 
      end; 
      else 
      end; 
      CertPropId := CertEnumCertificateContextProperties(CertContext, 
      CertPropId); 
     end; 
     CertContext := CertEnumCertificatesInStore(hStore, CertContext); 
     end; 
//  if GetLastError <> CRYPT_E_NOT_FOUND then 
//  RaiseLastWin32Error; 
    finally 
     CertCloseStore(hStore, 0); 
    end; 
    except 
    on E: Exception do 
    begin 
     ExitCode := 1; 
     Writeln(Format('[%s] %s', [E.ClassName, E.Message])); 
    end; 
    end; 
end. 
6

Bạn có thể thực hiện mọi thứ với SecureBlackBox của EldoS. http://www.eldos.com/sbb/

Phần mềm này có vẻ dễ dàng. Nó không dẽ.

+0

Tôi đồng ý với Chris, tôi đã có vinh dự được làm việc với các phiên bản trước đó, và nó đã rất tốt đẹp. Tuy nhiên, tôi không còn quyền truy cập vào nó nữa. Nếu ngân sách của bạn cho phép, hãy mua điều này và làm cho cuộc sống của bạn trở nên dễ dàng. Nó cũng trở nên phức tạp với nhiều gói của họ để nói chuyện với họ để tìm ra chính xác cái nào bạn cần. Nó đi kèm với một phiên bản fpc. –

+1

Gói PKIBlackBox là những gì bạn cần. Tuy nhiên, bạn chỉ cần đi trước và nhận được đầy đủ SecureBlackBox Professional guacamole. Nó không phải là rẻ (hơn một ngàn đô la) nhưng nó là giá trị mỗi penny. –

4

Tôi khuyên bạn nên Eldos SecureBlackBox, nhưng có một giải pháp thay thế miễn phí.

Bạn cũng có thể sử dụng thư viện OpenSSL. Bạn sẽ cần một cổng OpenSSL đầy đủ, vì các tiêu đề Indy OpenSSL không đầy đủ. Bạn cũng sẽ cần phải biên dịch một cơ sở dữ liệu các chứng chỉ công khai từ các cơ quan cấp chứng chỉ vì nó không được bao gồm.

Với OpenSSL, bạn sẽ không có quyền truy cập trực tiếp vào kho chứng chỉ Windows. Bạn có thể xuất các chứng chỉ từ Windows hoặc Firefox và nhập chúng.

Eldos SecureBlackBox cung cấp quyền truy cập vào cửa hàng chứng chỉ Windows, bao gồm các phương pháp để xác minh chữ ký ký mã của chương trình.

Bạn có thể bao gồm các tệp nhị phân OpenSSL với sản phẩm Windows của mình và OpenSSL đã được cài đặt và có sẵn trên Mac OS. Vì vậy, OpenSSL là khả thi cho FireMonkey hoặc Lazarus.

OpenSSL là tài liệu khá tốt và bạn có thể tìm thấy rất nhiều ví dụ trực tuyến, mặc dù chủ yếu là trong C hoặc C++. Tôi đã may mắn thực hiện bất cứ điều gì tôi cần với nó. Nó có rất nhiều chức năng để đọc và ghi vào các tệp PEM.

SecureBlackBox chưa có phiên bản FireMonkey, nhưng họ cho biết họ sẽ có một năm tiếp theo (theo diễn đàn của họ). Họ có một phiên bản fpc (miễn phí pascal).

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