我有一个delphi 7 CGI webService(在Windows XP中,但Windows 7不在表中)应用程序,我需要访问数字证书来签署XML文档。
我已经导入了CApicom_TLB并成功实例化了证书,但是有一些问题......
运行我的应用程序的 Apache 服务器使用我在其中安装证书的不同 Windows 用户运行它,当我使用 CAPICOM_CURRENT_USER_STORE 标志查询时,证书存储区将为空。我通过在本地计算机中安装 A1 证书(带有私钥的 Pfx)(通过 MMC 控制台,添加新的管理单元)并使用 CAPICOM_LOCAL_MACHINE_STORE 标志访问证书存储来解决这个问题。我获得了证书(我可以读取其序列号、友好名称、迄今为止有效),但是当我尝试签署文档时,出现“密钥对不存在”错误。
相同的代码可以在具有相同 PFx 的普通应用程序(非 cgi)中工作(成功签署 XML)。
我用来获取证书的代码:
Store := CoStore.Create;
Store.Open(CAPICOM_LOCAL_MACHINE_STORE, CAPICOM_STORE_NAME, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
Certs := Store.Certificates as ICertificates2;
for i:= 1 to Certs.Count do
begin
Cert := IInterface(Certs.Item[i]) as ICertificate2;
if Cert.SerialNumber = FNumeroSerie
then begin
if DFeUtil.EstaVazio(NumCertCarregado)
then NumCertCarregado := Cert.SerialNumber;
if CertStoreMem = nil
then begin
CertStoreMem := CoStore.Create;
CertStoreMem.Open(CAPICOM_MEMORY_STORE, 'Memoria', CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED);
CertStoreMem.Add(Cert);
end;
然后我使用 CertStoreMem 使用以下内容进行签名
OleCheck(IDispatch(Certificado.PrivateKey).QueryInterface(IPrivateKey,PrivateKey));
xmldsig.store := CertStoreMem;
dsigKey := xmldsig.createKeyFromCSP(PrivateKey.ProviderType, PrivateKey.ProviderName, PrivateKey.ContainerName, 0);
错误(密钥对)位于代码的最后一行。
有两种方法:使 CGI 应用程序读取安装它的同一用户中的证书(在非 CGI 中工作的代码)或使此解决方法与本地计算机安装的证书一起工作而不会出现密钥错误。
如果有人可以提供帮助,将不胜感激
如果这是用户身份验证的问题,并且您对服务器有(完全)控制权,我会考虑将签名位包装在 Active X 库中,并将其添加到 COM+ 包中;使用组件服务,您可以控制激活和身份验证,以便它在单独的 dllhost.exe 中模拟运行