我已经按照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());
}
正是我想用Delphi使用CryptoAPI(JwaWinCrypt.pas) 我试过以下代码:
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什么都没显示,字符串是空的。 有人知道我做错了吗?
答案 0 :(得分: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
。