DELPHI实现标准SHA1WithRSA、MD5WithRSA算法

来源:互联网 发布:js table tr td 编辑:程序博客网 时间:2024/06/06 06:29

 

也可以直接看这里: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

 

原创粉丝点击