DELPHI实现标准SHA1WithRSA、MD5WithRSA算法

admin 2019-8-29 5639


本文来自:https://www.csdndoc.com/article/1779276
-----------------------------
也可以直接看这里:http://www.bmt-online.org/geekisms/RSA_verify

工作中遇到这样一个问题,双方通过HTTPS通信,对方提供了密钥及签名验签接口,是JAVA写的,由于某些限制,我只能用客户端与之通信,所以先用Swing写了一个,但实际运行时发现占用资源较大,便计划用DELPHI实现,于是问题来了,在网上翻了个底朝天,没找到现成的方法,这个是最接近的了(http://www.cnblogs.com/midea0978/articles/768824.html),可是它提供的DLL也没调用成功,只好自己实现。
首先我很弱的认为,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

最新回复 (0)
返回