詳解PHP版本兼容之openssl調(diào)用參數(shù)_第1頁(yè)
詳解PHP版本兼容之openssl調(diào)用參數(shù)_第2頁(yè)
詳解PHP版本兼容之openssl調(diào)用參數(shù)_第3頁(yè)
詳解PHP版本兼容之openssl調(diào)用參數(shù)_第4頁(yè)
詳解PHP版本兼容之openssl調(diào)用參數(shù)_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第詳解PHP版本兼容之openssl調(diào)用參數(shù)背景與問題解決方式

老項(xiàng)目重構(gòu)支付寶部分代碼整合支付寶新的sdk時(shí)發(fā)現(xiàn)驗(yàn)簽總是失敗,才發(fā)現(xiàn)是open_verify最后的參數(shù)傳輸問題。而open_sign同樣如此。本文主要說明open_verify的解決方式和代碼解析。而問題的解決方式也是修改最后的加密類型參數(shù),解決方式代碼如下:

//將最后的常量OPENSSL_ALGO_SHA256修改成字符串

openssl_verify($data,base64_decode($sign),$res,"sha256WithRSAEncryption");

官方文檔解釋

上面只說了問題的出現(xiàn)與對(duì)應(yīng)的解決方式,如果有興趣繼續(xù)了解該函數(shù)的,可以繼續(xù)往下讀,首先來看下官方文檔對(duì)此函數(shù)的解釋。

intopenssl_verify(string$data,string$signature,mixed$pub_key_id[,mixed$signature_alg=OPENSSL_ALGO_SHA1])

參數(shù)注釋

data

以前用來生成簽名的數(shù)據(jù)字符串。

signature

原始二進(jìn)制字符串,通過openssl_sign()或類似的函數(shù)生成。

pub_key_id

resource-一個(gè)密鑰,通過openssl_get_publickey()函數(shù)返回。

string-一個(gè)PEM格式的密鑰,比如,“—–BEGINPUBLICKEY—–MIIBCgK…”

signature_alg

int-以下簽名算法之一SignatureAlgorithms.

string-由openssl_get_md_methods()函數(shù)返回的可用字符串,比如,“sha1WithRSAEncryption”或者“sha512”.

官方文檔給出的signature_alg參數(shù)可以為int或者string類型,int類型直接調(diào)用對(duì)應(yīng)的枚舉值,string則是openssl_get_md_methods函數(shù)返回的可用字符串,調(diào)用openssl_get_md_methods方法打印參數(shù)如下,而這些字符串也是對(duì)應(yīng)加密方式的摘要信息,后文源碼中可能會(huì)看的對(duì)函數(shù)調(diào)用稍微明白那么一丟丟。

Array

(

[0]=DSA

[1]=DSA-SHA

[2]=DSA-SHA1

[3]=DSA-SHA1-old

[4]=DSS1

[5]=GOST28147-89MAC

[6]=GOSTR34.11-94

[7]=MD4

[8]=MD5

[9]=MDC2

[10]=RIPEMD160

[11]=RSA-MD4

[12]=RSA-MD5

[13]=RSA-MDC2

[14]=RSA-RIPEMD160

[15]=RSA-SHA

[16]=RSA-SHA1

[17]=RSA-SHA1-2

[18]=RSA-SHA224

[19]=RSA-SHA256

[20]=RSA-SHA384

[21]=RSA-SHA512

[22]=SHA

[23]=SHA1

[24]=SHA224

[25]=SHA256

[26]=SHA384

[27]=SHA512

[28]=dsaEncryption

[29]=dsaWithSHA

[30]=dsaWithSHA1

[31]=dss1

[32]=ecdsa-with-SHA1

[33]=gost-mac

[34]=md4

[35]=md4WithRSAEncryption

[36]=md5

[37]=md5WithRSAEncryption

[38]=md_gost94

[39]=mdc2

[40]=mdc2WithRSA

[41]=ripemd

[42]=ripemd160

[43]=ripemd160WithRSA

[44]=rmd160

[45]=sha

[46]=sha1

[47]=sha1WithRSAEncryption

[48]=sha224

[49]=sha224WithRSAEncryption

[50]=sha256

[51]=sha256WithRSAEncryption

[52]=sha384

[53]=sha384WithRSAEncryption

[54]=sha512

[55]=sha512WithRSAEncryption

[56]=shaWithRSAEncryption

[57]=ssl2-md5

[58]=ssl3-md5

[59]=ssl3-sha1

[60]=whirlpool

)

由此也可看出函數(shù)是兼容兩種模式的,但是為什么php版本會(huì)有兼容問題么?在openssl庫(kù)版本是一致的情況下,接下來的原因應(yīng)該只遺留在php擴(kuò)展的問題上。那下面來看看對(duì)應(yīng)的源碼去發(fā)現(xiàn)問題出現(xiàn)在哪吧。

函數(shù)源碼

openssl_verify函數(shù)源碼

openssl_verify源碼中有這樣一段,如果參數(shù)method為string類型的時(shí)候,調(diào)用openssl庫(kù)的EVP_get_digestbyname方法,在網(wǎng)上查看了下此方法的作用,主要是根據(jù)摘要信息返回

EVP_MD結(jié)構(gòu),而EVP_get_digestbyname方法由于是openssl庫(kù)源代碼并且對(duì)C語(yǔ)言知之甚少,熊某就沒去查看,

只是了解php代碼調(diào)用背后的一些處理邏輯,有興趣的可以看看openssl庫(kù)的代碼實(shí)現(xiàn)。

if(method==NULL||Z_TYPE_P(method)==IS_LONG){

if(method!=NULL){

signature_algo=Z_LVAL_P(method);

mdtype=php_openssl_get_evp_md_from_algo(signature_algo);

}elseif(Z_TYPE_P(method)==IS_STRING){

mdtype=EVP_get_digestbyname(Z_STRVAL_P(method));

}else{

php_error_docref(NULL,E_WARNING,"Unknownsignaturealgorithm.");

RETURN_FALSE;

}

原來是枚舉值的問題?

一開始本人以為php5.3版本會(huì)是method參數(shù)類型的限制,一看源代碼才發(fā)現(xiàn),openssl_verify函數(shù)的實(shí)現(xiàn)邏輯是一致的,都是檢測(cè)method參數(shù)類型,那么問題就不出現(xiàn)在參數(shù)類型上,然后我查看了參數(shù)為long類型是所調(diào)用的php_openssl_get_evp_md_from_algo函數(shù),果然發(fā)現(xiàn)了問題所在。源碼如下:

php5.3.27

staticEVP_MD*php_openssl_get_evp_md_from_algo(longalgo){/*{{{*/

EVP_MD*mdtype;

switch(algo){

caseOPENSSL_ALGO_SHA1:

mdtype=(EVP_MD*)EVP_sha1();

break;

caseOPENSSL_ALGO_MD5:

mdtype=(EVP_MD*)EVP_md5();

break;

caseOPENSSL_ALGO_MD4:

mdtype=(EVP_MD*)EVP_md4();

break;

#ifdefHAVE_OPENSSL_MD2_H

caseOPENSSL_ALGO_MD2:

mdtype=(EVP_MD*)EVP_md2();

break;

#endif

caseOPENSSL_ALGO_DSS1:

mdtype=(EVP_MD*)EVP_dss1();

break;

default:

returnNULL;

break;

returnmdtype;

}

php7.1.18

staticEVP_MD*php_openssl_get_evp_md_from_algo(zend_longalgo){/*{{{*/

EVP_MD*mdtype;

switch(algo){

caseOPENSSL_ALGO_SHA1:

mdtype=(EVP_MD*)EVP_sha1();

break;

caseOPENSSL_ALGO_MD5:

mdtype=(EVP_MD*)EVP_md5();

break;

caseOPENSSL_ALGO_MD4:

mdtype=(EVP_MD*)EVP_md4();

break;

#ifdefHAVE_OPENSSL_MD2_H

caseOPENSSL_ALGO_MD2:

mdtype=(EVP_MD*)EVP_md2();

break;

#endif

#ifOPENSSL_VERSION_NUMBER0x10100000L||defined(LIBRESSL_VERSION_NUMBER)

caseOPENSSL_ALGO_DSS1:

mdtype=(EVP_MD*)EVP_dss1();

break;

#endif

caseOPENSSL_ALGO_SHA224:

mdtype=(EVP_MD*)EVP_sha224();

break;

caseOPENSSL_ALGO_SHA256:

mdtype=(EVP_MD*)EVP_sha256();

break;

caseOPENSSL_ALGO_SHA384:

mdtype=(EVP_MD*)EVP_sha384();

break;

caseOPENSSL_ALGO_SHA512:

mdtype=(EVP_MD*)EVP_sha512();

break;

caseOPENSSL_ALGO_RMD1

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論