支付寶簽名驗證實現-Delphi版


支付寶簽名驗證實現-Delphi版

首先介結下支付寶簽名驗證流程:

 

 支付寶密鑰生成

支付寶提供秘鑰生成工具https://docs.open.alipay.com/291/105971/

用此下載此工具,生成相關RSA密鑰.

 

 

官網提供的PKCS8 PKCS1 如果不是JAVA的請用PKCS1

 

     如果已經用了PKCS8,Delphi要如何用呢?官網的工具也提供了轉換工具

 

 

那么這串就是其它要用到的密鑰.

 

打開密鑰文件路徑:就可以看到其它語言專用的密鑰。長度10242048多行.

打開密鑰文件:

 

 

 

其標准格式如上:我們可以看出其格式,頭尾多以----注釋---包圍,很重要,這個是標明此密鑰的格式。

 

 

 支付寶簽名過程https://docs.open.alipay.com/291/106118

 

 

 前面的多不難,很多人死在這一部。因為Delphi沒有提供標准庫證書算法.

 

Delpi如何實現:

 我們去看DELPHI Indy得知要實現這一功能需要引用

 

 

在各自的不同平台多有其對應的庫.

DELPHI indy也實現了對這些功能的擴展,其單元 IdSSLOpenSSLHeaders

此單元是indylibeay32庫擴展的PAS 里面實現了對接

   

  1. Libery32.dll用什么版本號.其實Delphi自代libery32.dll的我直接用自代的,最好用新版本會比較穩托.

我的開發環境是10.2.1DELPHI所要的DLL目錄如下

 

 

在其安裝目錄下就自代這貨了。。MSVCP100高版本的DLL需要這個配合使用,不然會提示少MSVCP100.DLL

       把相關DLL直接COPYEXE所在目錄即可

 

       有的低版本delphi其自代的DLL版本太低,或其DLL和現有的DELPHI IDDSLL單元不匹配.因此很多人重寫了

       Libery32.pas對接libery32.dll 這樣在什么樣的版本DELPHI 多可以適用。而且DELPHI自代的有的沒有把LIBER32.DLL功能實現,

       經過多方查找,終於找到一個重寫libery32.pas寫的比較好的庫,這個很重要,真的很重要。

       本人SVN地址:

           https://115.159.70.108:8443/svn/Super/OpenSSL

           賬號:read

           密碼:read

       請自行下載

  1. 簽名實現代碼如下

 

 

 

 

 

 

 

 

 

 

 

 

program mysign;

 

{$APPTYPE CONSOLE}

 

{$R *.res}

 

uses

  System.SysUtils,

  ssl_evp,

  ssl_bio,

  ssl_err,

  ssl_const,

  ssl_types,

  ssl_pem,

  ssl_engine,

  ssl_x509;

 

var

  certFile: AnsiString;

  PrivKey: AnsiString;

  signFile: AnsiString;

  Path: AnsiString;

  pkey: PEVP_PKEY;

  bp, mbp: PBIO;

  md_ctx: EVP_MD_CTX;

  Buf: AnsiString;

  Len: Integer;

  SigBuf: Array [0..4095] of AnsiChar;

  SigLen: Integer;

  InBuf: Array[0..511] of AnsiChar;

  _x509: PX509;

  b64: PBIO;

  a, i : Integer;

begin

  try

    { TODO -oUser -cConsole Main : Insert code here }

    Writeln('DEMO: mysign');

    //初始化工作

    SSL_InitPEM;

    SSL_InitERR;

    SSL_InitBIO;

    SSL_InitEVP;

    SSL_InitENGINE;

    SSL_InitX509;

 

    ENGINE_load_builtin_engines;

    OpenSSL_add_all_ciphers;

OpenSSL_add_all_digests;

 

    Path := ExtractFilePath(ParamStr(0));

    //支付寶生成的密鑰文件加載進來

    PrivKey := Path + 'private.pem';

    //sha1withRSA 簽名后得到的保存地址

    signFile := Path+'sign.pem';

 

    if (not FileExists(PrivKey)) then

     raise Exception.Create('PrivKey密鑰文件不存在');

    //簽名      sign_type=RSA2 RSA

    Buf := 'app_id=11111111&biz_content={"out_trade_no":"2017090517245110464476"}'+

           '&charset=UTF-8&format=JSON&method=alipay.trade.query&sign_type=RSA2&timestamp=2017-09-26 15:16:25&version=1.0';

    //如果用UTF-8UTF8編碼

Buf := UTF8Encode(Buf);

    Len := Length(Buf);

    Writeln('Sign test phrase: '+Buf);

{ Sign }

    bp := BIO_new_file(PAnsiChar(PrivKey), 'r');

    SSL_CheckError;

    try

     pkey := PEM_read_bio_PrivateKey(bp, nil, nil, nil);

     SSL_CheckError;

    finally

      BIO_free(bp);

    end;

 

    //如果是RSA2EVP_sha256 如果用RSAEVP_sha1

    EVP_SignInit(@md_ctx, EVP_sha256);

    SSL_CheckError;

    EVP_SignUpdate(@md_ctx, PAnsiChar(buf), len);

    SSL_CheckError;

 

    EVP_SignFinal(@md_ctx, @SigBuf, SigLen, pkey);

    SSL_CheckError;

    Writeln('Sign size ', SigLen, ' bytes');

 

    EVP_PKEY_free(pkey);

 

    bp := BIO_new_file(PAnsiChar(signFile), 'w');

 

    b64 := BIO_new(BIO_f_base64);

    mbp := BIO_push(b64, bp);

 

    BIO_write(mbp, @SigBuf, SigLen);

    BIO_flush(mbp);

    Writeln('Bytes written ', BIO_number_written(bp), ' file ', signFile);

    BIO_free_all(mbp);

{ End sign }

  except

    on E: Exception do

      Writeln(E.ClassName, ': ', E.Message);

  end;

end.      

 

 

好了,東東不多,但研究時是另一回事,本人也是研究了三天才得出的結果,最后簽名和支付寶簽名工具一至。。。哇哈哈。

聯系QQ:378464060 叫獸叔叔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM