工作需要根据资料写的一个SHA1RSA算法
工作需要根据资料写的一个SHA1RSA算法其中用到了libeay32.dll和ssleay32.dll,版本不限制,直接从官方下载源码然后编译
function ReadPrivateKey(AFileName: TFileName): pEVP_PKEY; //读取私钥文件
var
keyfile: pBIO;
function cb(buffer: PChar; blength: integer;
verify: integer; data: pointer): integer; cdecl;
var
Passphrase: String;
begin
result := 0;
end;
begin
keyfile := BIO_new(BIO_s_file());
BIO_read_filename(keyfile, PChar(AFilename));
result := PEM_read_bio_PrivateKey(keyfile, nil, @cb, nil);
BIO_free(keyfile);
end;
function ReadPublicKey(AFileName: TFileName): pEVP_PKEY;//读取公钥文件
var
keyfile: pBIO;
function cb(buffer: PChar; blength: integer;
verify: integer; data: pointer): integer; cdecl;
var
Passphrase: String;
begin
result := 0;
end;
begin
keyfile := BIO_new(BIO_s_file());
BIO_read_filename(keyfile, PChar(AFilename));
result := PEM_read_bio_PUBKEY(keyfile, nil, @cb, nil);
BIO_free(keyfile);
end;
function SHA1RSA_Sign(str, keystr: string):string;//签名
var
fp: TextFile;
key: pEVP_PKEY;
mdLength: dword;
mdValue: array [0..2200] of byte;
mdctx: EVP_MD_CTX;
inbuf: array [0..1023] of char;
dirname, ss, keyfile: string;
i: integer;
begin
result:= '';
ss:= '';
dirname:= ExtractFilePath(paramstr(0))+'key\';
Randomize;
keyfile:=dirname+ 'prv_'+ inttostr(Random(1000000))+ '.pem';
try
If not DirectoryExists(dirname) then
CreateDir(dirname);
try
AssignFile(fp, keyfile);
if not FileExists(keyfile) then
Rewrite(fp);
Append(fp);
Writeln(fp, keystr);
Flush(fp);
CloseFile(fp);
except
Flush(fp);
CloseFile(fp);
raise;
end;
except
end;
try
key := ReadPrivateKey(keyfile);
finally
deletefile(keyfile);
end;
if key <> nil then
begin
try
StrPCopy(inbuf, str);
EVP_SignInit(@mdctx, EVP_sha1());
EVP_SignUpdate(@mdctx, @inbuf, StrLen(inbuf));
mdLength:= 0;
EVP_SignFinal(@mdctx, @mdValue, mdLength, key);
for i:= 0 to mdLength- 1 do
ss:= ss+inttohex(mdValue,2);
result :=ss;
finally
EVP_PKEY_free(key);
end;
end;
end;
function SHA1RSA_Verify(plainstr, pubkeystr, sigstr:string):boolean;//对比认证
var
fp: TextFile;
key: pEVP_PKEY;
mdLength: dword;
mdValue: array [0..2200] of byte;
mdctx: EVP_MD_CTX;
inbuf: array [0..1023] of char;
dirname, ss, keyfile: string;
i,ret: integer;
begin
result:= false;
ss:= '';
dirname:= ExtractFilePath(paramstr(0))+'key\';
Randomize;
keyfile:=dirname+ 'pub_'+ inttostr(Random(1000000))+ '.pem';
try
If not DirectoryExists(dirname) then
CreateDir(dirname);
try
AssignFile(fp, keyfile);
if not FileExists(keyfile) then
Rewrite(fp);
Append(fp);
Writeln(fp, pubkeystr);
Flush(fp);
CloseFile(fp);
except
Flush(fp);
CloseFile(fp);
raise;
end;
except
end;
try
key := ReadPublicKey(keyfile);
finally
deletefile(keyfile);
end;
if key <> nil then
begin
try
StrPCopy(inbuf, plainstr);
EVP_VerifyInit(@mdctx, EVP_sha1());
EVP_VerifyUpdate(@mdctx, @inbuf, StrLen(inbuf));
mdLength := 128;
for i:= 0 to 127 do
begin
mdValue:= strtoint('$'+sigstr[2*i+1]+sigstr[2*i+2]);
ss:= ss+ inttostr(strtoint('$'+sigstr[2*i+1]+sigstr[2*i+2]));
end;
ret:= EVP_VerifyFinal(@mdctx,@mdValue, mdLength, key);
if ret= 1 then
result:= true;
finally
EVP_PKEY_free(key);
end;
end;
end;
function ReadPrivateKey(AFileName: TFileName): pEVP_PKEY; //读取私钥文件
var
keyfile: pBIO;
function cb(buffer: PChar; blength: integer;
verify: integer; data: pointer): integer; cdecl;
var
Passphrase: String;
begin
result := 0;
end;
begin
keyfile := BIO_new(BIO_s_file());
BIO_read_filename(keyfile, PChar(AFilename));
result := PEM_read_bio_PrivateKey(keyfile, nil, @cb, nil);
BIO_free(keyfile);
end;
function ReadPublicKey(AFileName: TFileName): pEVP_PKEY;//读取公钥文件
var
keyfile: pBIO;
function cb(buffer: PChar; blength: integer;
verify: integer; data: pointer): integer; cdecl;
var
Passphrase: String;
begin
result := 0;
end;
begin
keyfile := BIO_new(BIO_s_file());
BIO_read_filename(keyfile, PChar(AFilename));
result := PEM_read_bio_PUBKEY(keyfile, nil, @cb, nil);
BIO_free(keyfile);
end;
function SHA1RSA_Sign(str, keystr: string):string;//签名
var
fp: TextFile;
key: pEVP_PKEY;
mdLength: dword;
mdValue: array [0..2200] of byte;
mdctx: EVP_MD_CTX;
inbuf: array [0..1023] of char;
dirname, ss, keyfile: string;
i: integer;
begin
result:= '';
ss:= '';
dirname:= ExtractFilePath(paramstr(0))+'key\';
Randomize;
keyfile:=dirname+ 'prv_'+ inttostr(Random(1000000))+ '.pem';
try
If not DirectoryExists(dirname) then
CreateDir(dirname);
try
AssignFile(fp, keyfile);
if not FileExists(keyfile) then
Rewrite(fp);
Append(fp);
Writeln(fp, keystr);
Flush(fp);
CloseFile(fp);
except
Flush(fp);
CloseFile(fp);
raise;
end;
except
end;
try
key := ReadPrivateKey(keyfile);
finally
deletefile(keyfile);
end;
if key <> nil then
begin
try
StrPCopy(inbuf, str);
EVP_SignInit(@mdctx, EVP_sha1());
EVP_SignUpdate(@mdctx, @inbuf, StrLen(inbuf));
mdLength:= 0;
EVP_SignFinal(@mdctx, @mdValue, mdLength, key);
for i:= 0 to mdLength- 1 do
ss:= ss+inttohex(mdValue
result :=ss;
finally
EVP_PKEY_free(key);
end;
end;
end;
function SHA1RSA_Verify(plainstr, pubkeystr, sigstr:string):boolean;//对比认证
var
fp: TextFile;
key: pEVP_PKEY;
mdLength: dword;
mdValue: array [0..2200] of byte;
mdctx: EVP_MD_CTX;
inbuf: array [0..1023] of char;
dirname, ss, keyfile: string;
i,ret: integer;
begin
result:= false;
ss:= '';
dirname:= ExtractFilePath(paramstr(0))+'key\';
Randomize;
keyfile:=dirname+ 'pub_'+ inttostr(Random(1000000))+ '.pem';
try
If not DirectoryExists(dirname) then
CreateDir(dirname);
try
AssignFile(fp, keyfile);
if not FileExists(keyfile) then
Rewrite(fp);
Append(fp);
Writeln(fp, pubkeystr);
Flush(fp);
CloseFile(fp);
except
Flush(fp);
CloseFile(fp);
raise;
end;
except
end;
try
key := ReadPublicKey(keyfile);
finally
deletefile(keyfile);
end;
if key <> nil then
begin
try
StrPCopy(inbuf, plainstr);
EVP_VerifyInit(@mdctx, EVP_sha1());
EVP_VerifyUpdate(@mdctx, @inbuf, StrLen(inbuf));
mdLength := 128;
for i:= 0 to 127 do
begin
mdValue
ss:= ss+ inttostr(strtoint('$'+sigstr[2*i+1]+sigstr[2*i+2]));
end;
ret:= EVP_VerifyFinal(@mdctx,@mdValue, mdLength, key);
if ret= 1 then
result:= true;
finally
EVP_PKEY_free(key);
end;
end;
end;