I am experimenting with OpenSSL for Delphi a unit that you can find here . So far I am able to generate a public / private key. What I am trying to do is sign a string and then check if the string is signed with the public key.
So.. here is what I have so far. The problem is that EVP_SignFinal causes an access violation because EVP_PKEY_assign always returns pKey = nil so I guess the key is not assigned from the memory how can I assign It.
PS . You have to excuse the code is just a test 😉
Could somebody point me where I am wrong ?
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;
I think the mistake is that you are trying to sign with the public key instead of the private key. You always use the public key for encryption (and the private for decryption) and the private key for signing (and thus the public key for verification).
Furthermore, it seems to me that it is better to use
PEM_read_bio_RSAPrivateKeyinstead ofEVP_PKEY_assign, as it seems to be the direct opposite ofPEM_write_bio_RSAPrivateKey.EVP_PKEY_assignseems to be a deprecated call, and is unlikely to handle PEM encoding.