我正在尝试使用OpenSSL for Delphi,你可以找到here。到目前为止,我能够生成公钥/私钥。我要做的是签署一个字符串,然后检查该字符串是否使用公钥签名。
所以..这就是我到目前为止所拥有的。问题是 EVP_SignFinal 会导致访问冲突,因为 EVP_PKEY_assign 总是返回pKey = nil所以我猜这个密钥没有从内存中分配,我该如何分配它。
PS。你必须原谅代码只是一个测试;)
有人能指出我错在哪里吗?
var
rsa : pRSA;
eu : string;
privateKey,publicKey,Err : pBIO;
enc : pEVP_CIPHER;
keylen : Cardinal;
prv,pub : PChar;
hash : TMD5Digest;
mdctx : EVP_MD_CTX;
pkey : pEVP_PKEY;
lbuf : array [0..15] of Byte;
i : Integer;
begin
ERR_load_crypto_strings;
OpenSSL_add_all_algorithms;
OpenSSL_add_all_ciphers;
OpenSSL_add_all_digests;
eu := 'SIGN THIS';
enc := EVP_des_ede3_cbc;
rsa := RSA_generate_key(1024,RSA_F4,nil,Err);
if rsa <> nil then
begin
privateKey := BIO_new(BIO_s_mem);
PEM_write_bio_RSAPrivateKey(privateKey,rsa,enc,nil,0,nil,PChar('0PC0DE'));
publicKey := BIO_new(BIO_s_mem);
PEM_write_bio_RSAPublicKey(publicKey,rsa);
keylen := BIO_pending(privateKey);
GetMem(prv,keylen + 1);
BIO_read(privateKey,prv,keylen);
keylen := BIO_pending(publicKey);
GetMem(pub,keylen + 1);
BIO_read(publicKey,pub,keylen);
Writeln(prv);
Writeln('Keys generated!');
pKey := nil;
EVP_PKEY_assign(pkey,EVP_PKEY_RSA,pub);
EVP_MD_CTX_init(@mdctx);
EVP_SignInit(@mdctx,EVP_md5());
EVP_SignUpdate(@mdctx,PChar(eu),Length(eu));
EVP_SignFinal(@mdctx,@lbuf,keylen,pkey);
EVP_MD_CTX_cleanup(@mdctx);
WriteLn(keylen);
Readln;
end;
end;
答案 0 :(得分:2)
我认为错误在于您尝试使用公钥而不是私钥进行签名。您始终使用公钥进行加密(以及用于解密的私有密钥)和用于签名的私钥(以及用于验证的公钥)。
此外,在我看来,最好使用PEM_read_bio_RSAPrivateKey
代替EVP_PKEY_assign
,因为它似乎与PEM_write_bio_RSAPrivateKey
正好相反。 EVP_PKEY_assign
似乎是一个不推荐的调用,并且不太可能处理PEM编码。