支付寶簽名驗證實現-Delphi版
支付寶簽名驗證實現-Delphi版
首先介結下支付寶簽名驗證流程:
一 支付寶密鑰生成
支付寶提供秘鑰生成工具https://docs.open.alipay.com/291/105971/
用此下載此工具,生成相關RSA密鑰.
官網提供的PKCS8 和PKCS1 如果不是JAVA的請用PKCS1。
如果已經用了PKCS8的,Delphi要如何用呢?官網的工具也提供了轉換工具
那麽這串就是其它要用到的密鑰.
打開密鑰文件路徑:就可以看到其它語言專用的密鑰。長度1024,2048多行.
打開密鑰文件:
其標準格式如上:我們可以看出其格式,頭尾多以----註釋
二 支付寶簽名過程: https://docs.open.alipay.com/291/106118
前面的多不難,很多人死在這一部。因為Delphi沒有提供標準庫證書算法.
三 Delpi如何實現:
我們去看DELPHI Indy得知要實現這一功能需要引用
在各自的不同平臺多有其對應的庫.
DELPHI indy也實現了對這些功能的擴展,其單元 IdSSLOpenSSLHeaders
此單元是indy基libeay32庫擴展的PAS 裏面實現了對接
- Libery32.dll用什麽版本號.其實Delphi自代libery32.dll
我的開發環境是10.2.1其DELPHI所要的DLL目錄如下
在其安裝目錄下就自代這貨了。。MSVCP100高版本的DLL需要這個配合使用,不然會提示少MSVCP100.DLL
把相關DLL直接COPY到EXE所在目錄即可
有的低版本delphi其自代的DLL版本太低,或其DLL和現有的DELPHI IDDSLL單元不匹配.因此很多人重寫了
Libery32.pas對接libery32.dll 這樣在什麽樣的版本DELPHI 多可以適用。而且DELPHI自代的有的沒有把LIBER32.DLL功能實現,
經過多方查找,終於找到一個重寫
本人SVN地址:
https://115.159.70.108:8443/svn/Super/OpenSSL
賬號:read
密碼:read
請自行下載
- 簽名實現代碼如下
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×tamp=2017-09-26 15:16:25&version=1.0‘;
//如果用UTF-8請UTF8編碼
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;
//如果是RSA2用 EVP_sha256 如果用RSA用 EVP_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 叫獸叔叔
支付寶簽名驗證實現-Delphi版