我有一个使用证书对字符串进行签名的Java应用程序。它使用SHA1加密该字符串。我正在尝试将代码转换为Delphi 2010,但我不知道如何使其以与Java应用程序相同的方式工作(使用sha1)。到目前为止,我找到了这个:
它可以工作,但它不使用sha1,并且在运行java应用程序时得到不同的结果。
Java代码
char[] pass = (char[]) null;
PrivateKey key = (PrivateKey) getKeyStore().getKey(alias, pass);
Certificate[] chain = getKeyStore().getCertificateChain(alias);
CertStore certsAndCRLs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(Arrays.asList(chain)), "BC");
X509Certificate cert = (X509Certificate) chain[0];
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addSigner(key, cert, CMSSignedDataGenerator.DIGEST_SHA1);
gen.addCertificatesAndCRLs(certsAndCRLs);
CMSProcessable data = new CMSProcessableByteArray(conteudoParaAssinar);
CMSSignedData signed = gen.generate(data, true, "SunMSCAPI");
byte[] envHex = signed.getEncoded();
CertInfo certInfo = new CertInfo();
certInfo.Hash = new BigInteger(envHex).toString(16);
return certInfo;
Delphi 代码
var
lSigner: TSigner;
lSignedData: TSignedData;
fs: TFileStream;
qt: integer;
ch: PChar;
msg : WideString;
content : string;
cert: TCertificate;
begin
cert := Self.GetCert;
content := 'test';
lSigner := TSigner.Create(self);
lSigner.Certificate := cert.DefaultInterface;
lSignedData := TSignedData.Create(self);
lSignedData.content := content;
msg := lSignedData.Sign(lSigner.DefaultInterface, false, CAPICOM_ENCODE_BASE64);
lSignedData.Free;
lSigner.Free;
编辑
根据Java代码,我应该以二进制格式获取证书信息,对其应用SHA1,然后将其转换为十六进制吗?这是正确的顺序和Java代码执行的相同步骤吗?我可以在capicom tlb中看到一些SHA1常量以及哈希类,也许我应该使用这些类,但我不知道如何使用。