也可以直接看这里:http://www.bmt-online.org/geekisms/RSA_verify
首先我很弱的认为,SHA1WithRSA就是先做SHA1摘要再做RSA加密,尝试,失败!
然后找到这个http://tools.ietf.org/html/rfc3447,英文版,名词太多,理解费尽,又去找了中文版,总算在8章9章找到解释,弄明白了原来还有一个利用摘要与摘要算法NID组装ASN.1数据的过程,传入RSA算法进行加密的就是这个组装后的数据。
但是具体要如何做呢,又经过一番搜索,找到了这(http://www.cnblogs.com/adylee/archive/2009/08/03/1537813.html),第六部分虽然是证书签名,但是后面部分完全可以取之已用,原来ASN.1的组装部分OpenSSL在RSA_Sign函数中已经为我们做了,这下问题就几乎解决了,找了一个封装libeay32.DLL的单元,总算解决了问题。部分代码如下:
function TForm1.LoadPrivateKey(filename, password:string ): PEVP_PKEY;
var
bp : PBIO ;
pkey :PEVP_PKEY ;
begin
bp := BIO_new(BIO_s_file()) ;
BIO_read_filename(bp, PChar(filename));
pkey := PEM_read_bio_PrivateKey(bp, nil, nil, PChar(password));
BIO_free(bp);
Result:= pkey;
end;
function TForm1.Sign(msg : String):string;
var
ctx : EVP_MD_CTX ;
buf_in:Pchar;
m_len,outl :cardinal;
pKey : PEVP_PKEY;
m,buf_out:array [0..1024] of char;
p:array [0..255] of char;
i:Integer;
begin
pKey := LoadPrivateKey('私钥文件');
buf_in := PChar(msg);
EVP_MD_CTX_init(@ctx); //初始化
EVP_SignInit(@ctx,EVP_sha1()); //将需要使用的摘要算法存入ctxl中
EVP_SignUpdate(@ctx,buf_in,Length(buf_in));//存入编码值
EVP_DigestFinal(@ctx,m,m_len); //求取编码的长度为m_len摘要值存入m中
RSA_sign(EVP_sha1()._type,m,m_len,buf_out,@outl,pKey.pkey.rsa); //64为SHA1的NID
BinToHex(buf_out,p,outl);
EVP_MD_CTX_cleanup(@ctx);
for i:= 0 to High(p) do
begin
Result := Result+ p[i];
end;
end;
同样MD5WithRSA或者其他摘要算法WithRSA也可以这种方法实现。
前前后后花费了几天的时间,真是浪费。
更详细的信息在这里:http://www.bmt-online.org/geekisms/RSA_verify