我已经得到了下面的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什么都不显示,字符串是空的。有人知道我做错了什么吗?
2条答案
按热度按时间tf7tbtn21#
CryptBinaryToString
的文档是这样描述pszString
参数的。指向接收转换后字符串的缓冲区的指针。要计算必须分配以保存返回字符串的字符数,请将此参数设置为NULL。此函数将在pcchString指向的值中放置所需数量的字符,包括终止NULL字符。
您必须分配缓冲区,以便API函数可以填充它。您未能执行此操作。为了继续,您必须仔细阅读文档并遵守API的要求。
所以你需要像这样调用这个函数:
您还应该检查
CryptBinaryToString
的返回值以检测故障,为了简洁起见,我省略了这一点。我还假设你的是ANSI Delphi 。我假设是因为你使用了
PAnsiChar
。ybzsozfc2#
不应该是这样的吗:
对CryptBinaryToString的第一次调用返回包括NULL终止符的长度,因此调整字符串的大小以允许字符串数据和NULL终止符。
对CryptBinaryToString的第二次调用使用包括NULL终止符的字符串数据填充szString,但它返回的长度值不包括NULL终止符,因此只需再次调用SetLength来调整大小以删除NULL终止符。