3

件名で要求したことを実行するための次の C# コードがあります。

public static void ExportCertificatesToFile(string FileName)
{
    stringBuilder builder = new StringBuilder();

    X509Store storeMy = new X509Store(StoreName.My);
    storeMy.Open(OpenFlags.ReadOnly);

    foreach (X509Certificate2 cert in storeMy.Certificates)
    {
        builder.AppendLine("-----BEGIN CERTIFICATE-----");   
              builder.AppendLine(Convert.ToBase64String(cert.Export(X509ContentType.Cert),  Base64FormattingOptions.InsertLineBreaks));
        builder.AppendLine("-----END CERTIFICATE-----");
    }

    storeMy.Close();

    File.WriteAllText(FileName, builder.ToString());
}

まさにCryptoAPI(JwaWinCrypt.pas)を使用してDelphiでアーカイブしたいので、次のコードを試しました:

procedure TForm1.Button1Click(Sender: TObject);
var
  hStore: HCERTSTORE;
  CertContext: PCertContext;
  pszString: PAnsiChar;
  pchString: Cardinal;
begin
  hStore := CertOpenSystemStore(0, PChar('MY'));

  try
    CertContext := CertEnumCertificatesInStore(hStore, nil);
    while CertContext <> nil do
    begin
      pszString := '';
      pchString := 0;
      CryptBinaryToString(CertContext.pbCertEncoded, CertContext.cbCertEncoded,  CRYPT_STRING_BASE64, pszString, pchString);

      ShowMessage(StrPas(pszString));

      CertContext := CertEnumCertificatesInStore(hStore, CertContext);
    end;
  finally
    CertCloseStore(hStore, 0);
  end;
end;

問題は、ShowMessage に何も表示されず、文字列が空であることです。誰かが私が間違っていることを知っていますか?

4

1 に答える 1

1

のドキュメントにCryptBinaryToStringは、パラメーターについてこれが記載されていpszStringます。

変換された文字列を受け取るバッファーへのポインター。返された文字列を保持するために割り当てる必要がある文字数を計算するには、このパラメーターを NULL に設定します。この関数は、pcchString が指す値に、終端の NULL 文字を含む必要な数の文字を配置します。

API 関数がバッファに入力できるように、バッファを割り当てる必要があります。あなたはそうしていません。続行するには、ドキュメントを注意深く読み、API の要件に従う必要があります。

したがって、次のように関数を呼び出す必要があります。

szString: AnsiString;
....
chString := 0;
CryptBinaryToString(CertContext.pbCertEncoded, CertContext.cbCertEncoded,  
    CRYPT_STRING_BASE64, nil, chString);
SetLength(szString, chString-1);
CryptBinaryToString(CertContext.pbCertEncoded, CertContext.cbCertEncoded,  
    CRYPT_STRING_BASE64, PAnsiChar(szString), chString);

CryptBinaryToString失敗を検出するために、 の戻り値もチェックする必要があります。簡潔にするためにそれを省略しました。

また、あなたが ANSI Delphi であると仮定しています。を使っていたからだと思いますPAnsiChar

于 2013-02-09T20:33:04.367 に答える