




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年藥師考試高級(jí)輔助用藥試題及答案
- 2025年即將到來的語(yǔ)文考試試題及答案
- 地方文化保護(hù)與地方經(jīng)濟(jì)發(fā)展的關(guān)系試題及答案
- 行政管理專業(yè)的語(yǔ)文學(xué)習(xí)方法試題及答案
- 2025衛(wèi)生資格考試重要知識(shí)點(diǎn)試題及答案
- 主管護(hù)師考試時(shí)間管理技巧與試題及答案
- 大學(xué)語(yǔ)文考試實(shí)踐類型題目及答案(2025年)
- 行政管理??屏鞒虄?yōu)化路徑試題及答案
- 護(hù)理責(zé)任與權(quán)利的平衡2025年試題及答案
- 地方歷史文化在政策制定中的作用試題及答案
- 合伙人協(xié)議書模板
- 2025年中考第一次模擬考試卷:生物(成都卷)解析版
- 歲月不負(fù)母親時(shí)光留住溫情 課件高二下學(xué)期母親節(jié)(5月11日)主題班會(huì)
- Unit 5 Animals Lesson 3 教學(xué)設(shè)計(jì)-人教精通版三年級(jí)英語(yǔ)下冊(cè)
- (正式版)SHT 3551-2024 石油化工儀表工程施工及驗(yàn)收規(guī)范
- 周三多-管理學(xué):原理與方法(第七版),第三章
- GB∕T 18998.2-2022 工業(yè)用氯化聚氯乙烯(PVC-C)管道系統(tǒng) 第2部分:管材
- 心肺復(fù)蘇后的亞低溫治療
- 武漢市農(nóng)村土地承包經(jīng)營(yíng)權(quán)轉(zhuǎn)包出租合同
- 蒸壓加氣混凝土砌塊施工方案:物流園完整版
- 施工場(chǎng)地移交單(共4頁(yè))
評(píng)論
0/150
提交評(píng)論