【小(xiǎo)編推薦】php OpenSSL✘§✘"用(yòng)法

2016-06-27  &nbs↔↕↕←p;|   發布者:梁國(λ↔εguó)芳   "§;|   查看(kàn):3320次

php
 公司一(yī)個(gè)項目要(yào)進行("₽‌€xíng)交易數(shù)據傳輸,因為(wè'↑γ←i)這(zhè)個(gè)項目銀(yín)行(xíng)那(nà)邊也(yě)©£★β是(shì)剛剛開(kāi)始啓動,所有(yǒu)£₩•÷的(de)支持隻有(yǒu)一(yī)個(g &±è)傳輸字段的(de)說(shuō)明(mΩ​íng)文(wén)檔,好(hǎo)吧(ba),總的(de)有(yǒu)人(r‍γ✘∏én)做(zuò)事(shì)不(bù)是(shì)&≤ε嘛,于是(shì)接口開(kāi)發正式展開(kāi),第一(yī)步的(↔>de)難點就(jiù)是(shì)加密解§±↑→密,我選擇使用(yòng)OpenSSL.

OpenSSL初接觸的(de)人(rén)恐怕最難的(de)在于先理(∏‌βlǐ)解各種概念

  公鑰/私鑰/簽名/驗證簽名/加密/解密/♦→非對(duì)稱加密

  我們一(yī)般的(de)加密是(shì)用(y♦πòng)一(yī)個(gè)密碼加密文(wén)件(jiàn),™♣然後解密也(yě)用(yòng)同樣的(de)密碼.這(z✘₩←hè)很(hěn)好(hǎo)理(lǐ)解,這(zhè)個(gè)是(shì•♥↑♠)對(duì)稱加密.而有(yǒu)些(xiē)加密時(shí↑ ),加密用(yòng)的(de)一(yī)個(gè)密碼,而解密用(yòng)§∏✔ 另外(wài)一(yī)組密碼,這(zhè)個(gè)叫≤§♦Ω非對(duì)稱加密,意思就(jiù)是(shì)加密解密的(de ¶)密碼不(bù)一(yī)樣.初次接觸的(d↕•e)人(rén)恐怕無論如(rú)何都(dōu)理(lǐ ♦£π)解不(bù)了(le).其實這(zhè)是(shì)數(shù)學上(sh→"àng)的(de)一(yī)個(gè)素↕π&數(shù)積求因子(zǐ)的(de)原理(± δlǐ)的(de)應用(yòng),如(r£ →ú)果你(nǐ)一(yī)定要(yào)搞™γ懂(dǒng),百度有(yǒu)大(dà)把大(dà)把的‍≥÷ε(de)資料可(kě)以看(kàn),其結果¶ '就(jiù)是(shì)用(yòng)這(zhè)§÷一(yī)組密鑰中的(de)一(yī)個(g¶✔è)來(lái)加密數(shù)據,可(↕↕kě)以用(yòng)另一(yī)個(gè§φ≤♠)解開(kāi).是(shì)的(de)沒錯(cuò)∞π,公鑰和(hé)私鑰都(dōu)可(kě)以用(yòng δ)來(lái)加密數(shù)據,相(xià>✘ng)反用(yòng)另一(yī)個(gè)解開(kāi),公鑰 ¶加密數(shù)據,然後私鑰解密的(de)情況被稱為(wè×✘§‌i)加密解密,私鑰加密數(shù)據,公鑰解密一(yī)般被稱為(wèi)簽©→ε名和(hé)驗證簽名.

  因為(wèi)公鑰加密的(de)數(shù)$☆←據隻有(yǒu)它相(xiàng)對(duì)應的(de)私♠≤÷φ鑰可(kě)以解開(kāi),所以你(nǐ)可(kě)以把公鑰給人(rén)和£ (hé)人(rén),讓他(tā)加密他(tā)想要(yào)傳送給你(nǐ§≈₹≠)的(de)數(shù)據,這(zhè)個(gè)數(shù)據隻有(yǒ₹₩↑u)到(dào)了(le)有(yǒu)私鑰的(de)你(nǐ)這(zh裕)裡(lǐ),才可(kě)以解開(kāi)成有(yǒu)用(yòng₹™≤≤)的(de)數(shù)據,其他(tā)人(rén)就(jiù)是(shì)‌'得(de)到(dào)了(le),也(yě)看(kàn)懂(↓&dǒng)內(nèi)容.同理(lǐ),如(rú)果你(nǐ)用(yòng)↓λ©你(nǐ)的(de)私鑰對(duì)數(shù)據進行(xíng)簽名,那(n♠™₹à)這(zhè)個(gè)數(shù)據就(jiù)隻有(yǒu¶♠≥)配對(duì)的(de)公鑰可(kě)以解開(kāi),有(yǒu)這(zhβ∑¥γè)個(gè)私鑰的(de)隻有(yǒu®φ↕)你(nǐ),所以如(rú)果配對(duΩ₽✔ ì)的(de)公鑰解開(kāi)了(le)數(s÷♠♥hù)據,就(jiù)說(shuō)明(₩→λ↕míng)這(zhè)數(shù)據是(•£♣shì)你(nǐ)發的(de),相(xiàng)反,則不(bù¥π)是(shì).這(zhè)個(gè)被稱為(wèi)簽名.

  實際應用(yòng)中,一(yī)般都(dōu)✔Ω是(shì)和(hé)對(duì)方交換公鑰,然後你(nǐ)₩♠φ'要(yào)發給對(duì)方的(de)數(shù)據,用(yòng₽®β)他(tā)的(de)公鑰加密,他(tā)得(de)到(d♦βγào)後用(yòng)他(tā)的(de)私鑰♣¥←↑解密,他(tā)要(yào)發給你(nǐ)的(de)數(shù)據'™,用(yòng)你(nǐ)的(de)公鑰加密,你(nǐ)得('≈de)到(dào)後用(yòng)你(nǐ)的(de)私鑰解密,這(zhè)∏'樣最大(dà)程度保證了(le)安全性.

  RSA/DSA/SHA/MD5

  非對(duì)稱加密的(de)算(suàn)法有(yǒu)λα♥很(hěn)多(duō),比較著名的(de)有(yǒu)R"↑SA/DSA ,不(bù)同的(de)是(shì)RSA可€→"≥(kě)以用(yòng)于加/解密,也(yě)可(kě)以用(≥​yòng)于簽名驗簽,DSA則隻能(néng)用(yòng)于簽名.至于SH"✔A則是(shì)一(yī)種和(hé)md5相(xiàng)同的(d↓×☆e)算(suàn)法,它不(bù)是(shì)✘≤∞用(yòng)于加密解密或者簽名的(de),它被稱為(wèi)摘要β☆(yào)算(suàn)法.就(jiù)是(sh®∑←ì)通(tōng)過一(yī)種算(suàn)法,依據數(shù)§ ×據內(nèi)容生(shēng)成一(y¥φ"πī)種固定長(cháng)度的(de)摘要(yào),這(z≤∑'•hè)串摘要(yào)值與原數(shù)據存在對(d§✔uì)應關系,就(jiù)是(shì)原數÷ε♣(shù)據會(huì)生(shēng)成這(zhè)個(gè)摘要(yào↓'¶¶),但(dàn)是(shì),這(zhè)個(gè)₹‌∑$摘要(yào)是(shì)不(bù)能(néng♠φβ)還(hái)原成原數(shù)據的(de),嗯....,正常情況下(x<✔→§ià)是(shì)這(zhè)樣的(de),這(zhè)個(gè)算(su>'àn)法起的(de)作(zuò)用(yòng)就(jiù←♥↕×)是(shì),如(rú)果你(nǐ)把原數(shù)據修¶↕改一(yī)點點,那(nà)麽生(shēng)成的(de)摘要(yào↓•'§)都(dōu)會(huì)不(bù)同,傳輸過程中✔™←把原數(shù)據給你(nǐ)再給你(nǐ)一£ε(yī)個(gè)摘要(yào),你(nǐ)把得(de)到(dào)©$↓π的(de)原數(shù)據同樣做(zuò©☆)一(yī)次摘要(yào)算(suàn)法,與給你(nǐ)的(de)摘要(y€✔Ωβào)相(xiàng)比較就(jiù)可(kě)以知(§♥♣"zhī)道(dào)這(zhè)個(gè)數(shù)據有(yǒu)沒有÷✔€ (yǒu)在傳輸過程中被修改了(le).

  實際應用(yòng)過程中,因為(wèi)需要(yào↕ )加密的(de)數(shù)據可(kě)能(nβ₩ε≈éng)會(huì)很(hěn)大(dà),進行(xíng)加密費(fèiδ∑​®)時(shí)費(fèi)力,所以一(yī)般都(dō↑&₩ u)會(huì)把原數(shù)據先進行(xíng)摘要₩σ↕✘(yào),然後對(duì)這(zhè)個(gè)λ÷σ 摘要(yào)值進行(xíng)加密,将原數(shù)據的(de‌∞™♠)明(míng)文(wén)和(hé)加密後∏‍的(de)摘要(yào)值一(yī)起傳給你(nǐ ≈).這(zhè)樣你(nǐ)解開(kāi)加密後的(de)摘要©☆↕ (yào)值,再和(hé)你(nǐ)得(de)到(dào)的πλ(de)數(shù)據進行(xíng)的(de)摘要(yào)值對(du​φ®ì)應一(yī)下(xià)就(jiù)可(kě)以知(zhī)道(dào)₽★≥♠數(shù)據有(yǒu)沒有(yǒu)被修改了(le),而且σσ↕Ω,因為(wèi)私鑰隻有(yǒu)你(nǐ§↑¶)有(yǒu),隻有(yǒu)你(nǐ)能(néng)解密摘要(‌←yào)值,所以别人(rén)就(jiù)算(suàn)把原數(shε↑α₩ù)據做(zuò)了(le)修改,然後生(shēng)成一(yī)個(gèαδ↕)假的(de)摘要(yào)給你(nǐ)也(yě)是↓∞(shì)不(bù)行(xíng)的(de),你(nǐ)這(zhè)邊用(↔∞<yòng)密鑰也(yě)根本解不(bù)開(kāi).

   CA/PEM/DER/X509/PKCS

  一(yī)般的(de)公鑰不(bù)會€×(huì)用(yòng)明(míng)文(wén)傳輸給别人(¶↕γrén)的(de),正常情況下(xià)都≈ Ω(dōu)會(huì)生(shēng)成一(yī)個(gè)文(σ∞wén)件(jiàn),這(zhè)個(gè)文(wén)件(ji™"àn)就(jiù)是(shì)公鑰文(wφ&∏én)件(jiàn),然後這(zhè)個(gè)文(wén)件(jià♣→‍δn)可(kě)以交給其他(tā)人(rén)用(yòng)ε$​σ于加密,但(dàn)是(shì)傳輸過程中如(r<&→ú)果有(yǒu)人(rén)惡意破壞,将你(nǐ)的(de)公鑰換成÷α '了(le)他(tā)的(de)公鑰,然後得(de)到(dào)公鑰的(d¥≥e)一(yī)方加密數(shù)據,不(bù)♦ε是(shì)他(tā)就(jiù)可(kě)以用(yòng)他('₹Ωtā)自(zì)己的(de)密鑰解密看(kàn)到(dào)數(shù​γβ)據了(le)嗎(ma),為(wèi)了(♣∞γ×le)解決這(zhè)個(gè)問(wèn)題,需要(yào)一(yī)個(g>₩è)公證方來(lái)做(zuò)這(zhè)個(gè)事(shì),∞✔任何人(rén)都(dōu)可(kě)以找它來(lái)确認公®→☆ 鑰是(shì)誰發的(de).這(zhè)就(jiùλ≥↓ )是(shì)CA,CA确認公鑰的(de)原¶ §≤理(lǐ)也(yě)很(hěn)簡單,它将它自(zì)己的(de)公鑰發布給所↑£®‍有(yǒu)人(rén),然後一(yī)個(gè)∞"♦←想要(yào)發布自(zì)己公鑰的(de)人(rén)可(kě)以将自(zì< σ)己的(de)公鑰和(hé)一(yī)些(xφ€≤₩iē)身(shēn)份信息發給CA,CA用(yòng±★)自(zì)己的(de)密鑰進行(xíng)加密,這(zh&☆è)裡(lǐ)也(yě)可(kě)以稱為(wèi)簽名.然後這(zhè)‍©個(gè)包含了(le)你(nǐ)的(de)公鑰和(hé)你(nǐ)的( ↑de)信息的(de)文(wén)件(jiàn)就(jiù)可(kě)以稱>↓​為(wèi)證書(shū)文(wén)件(jiàn)了(le).這(∞§zhè)樣一(yī)來(lái)所有(yǒu)得§"∑$(de)到(dào)一(yī)些(xiē)公鑰€‌‍文(wén)件(jiàn)的(de)人(rén),通(tōng)過ε∏≥CA的(de)公鑰解密了(le)文(wén)£α件(jiàn),如(rú)果正常解密那(nà)麽機(jī♣←)密後裡(lǐ)面的(de)信息一(yī)定是(shì)真≈‍Ω§的(de),因為(wèi)加密方隻可(kě)能(néng)是(✔δ‍£shì)CA,其他(tā)人(rén)沒它的(de)密鑰啊.這(zhè)樣 ♠©→你(nǐ)解開(kāi)公鑰文(wén)件(jiàn),看☆♣±∑(kàn)看(kàn)裡(lǐ)面的(de)信息就(jiù®∑)知(zhī)道(dào)這(zhè)個(gè)是(shì)不(bù)是γ♦♥∞(shì)那(nà)個(gè)你(nǐ)需要(yào)用(yòπ✘→ ng)來(lái)加密的(de)公鑰了(le).

  實際應用(yòng)中,一(yī)般人(rén)都↑≈ ↕(dōu)不(bù)會(huì)找CA去(qù)簽₽→λδ名,因為(wèi)那(nà)是(shì)≤₩☆σ收錢(qián)的(de),所以可(kě)以自(zì)己做(zuò)>"一(yī)個(gè)自(zì)簽名的(d‍₩e)證書(shū)文(wén)件(jiàn),就(j≥™iù)是(shì)自(zì)己生(shēng)‍ 成一(yī)對(duì)密鑰,然後再用(yòng)自(zì)π'己生(shēng)成的(de)另外(wài)一(yφ↑₩ī)對(duì)密鑰對(duì)這(zhè)對( ♣Ω"duì)密鑰進行(xíng)簽名,這(zhè)個(g'✔¶↔è)隻用(yòng)于真正需要(yào)簽名證書(s→ π£hū)的(de)人(rén),普通(tōng)的(de)加密解密數(shù)據‌₽ε,直接用(yòng)公鑰和(hé)私鑰來(lái)做(zu§£←Ωò)就(jiù)可(kě)以了(le).

  密鑰文(wén)件(jiàn)的(de)格式用(₩↓yòng)OpenSSL生(shēng)成的(de)就(jiù)隻有(y>×ǒu)PEM和(hé)DER兩種格式,PEM的(de)是(  shì)将密鑰用(yòng)base64編碼表示出來(lái)的(de),直∏ 接打開(kāi)你(nǐ)能(néng)看(kàn)到Ω×(dào)一(yī)串的(de)英文(wé ®π¶n)字母,DER格式是(shì)二進制(zhì)的(de)密鑰文(wéβ↕n)件(jiàn),直接打開(kāi),你(nǐ)可(kě)以看(k≈∞àn)到(dào)........你(nǐ)什(shén)麽也(yě)看(kà↔♠n)不(bù)懂(dǒng)!.X509是(shì)通(tō£★ng)用(yòng)的(de)證書(shū)文(wén)件(jiàn>‌)格式定義.pkcs的(de)一(yī)系列标準是(shì)指定 ♠♥的(de)存放(fàng)密鑰的(de)文(wén)件(™ jiàn)标準,你(nǐ)隻要(yào)知(zhī)≥&道(dào)PEM DER X509 PKCS這(zhè)幾種格式是(shì​γ)可(kě)以互相(xiàng)轉化(huà)的(de).

OpenSSL使用(yòng)

  PHP的(de)OpenSSL模塊要(yào∏§€)加載上(shàng)很(hěn)容易,百度一(yī)下(xi↓↔'à),按著(zhe)做(zuò)就(jiù)可>'(kě)以,但(dàn)是(shì)這(zhè)裡(lǐ)₹♦λ面其實有(yǒu)很(hěn)多(duō)問(wèn)題,首先一(y&₹ī)點就(jiù)是(shì)windows環境的(©™☆de)問(wèn)題,OpenSSL開(kāi)發是(shì)以©¶•βlinux環境為(wèi)基礎的(de),現(xiàn)在開(kāi)發> ✔₹者的(de)windows下(xià)lamp集成環境會(h€>" uì)出現(xiàn)很(hěn)多(duō≤₹★)錯(cuò)誤,如(rú)果你(nǐ)去(qù)φ¶  OpenSSL官網可(kě)以看(kàn)到(dà ±≤o)它提供了(le)專門(mén)的(d♦&♣€e)windows環境OpenSSL安裝包.遺憾的≠§™₩(de)是(shì),沒有(yǒu)提供給你(↔€‍nǐ)PHP調用(yòng)的(de)解決辦法,所以轉了(↓₽ ♣le)一(yī)圈我們又(yòu)回到(dào)PHP自(zì)帶的(d€∞e)php_openssl.dll下(xià)了(le),你(λγ↑nǐ)會(huì)發現(xiàn)在生(shēng)成證書(shū),提取公鑰α∞等等地(dì)方都(dōu)會(huì)出 π現(xiàn)錯(cuò)誤.我的(de)解決★ε¶∞辦法是(shì),在Apache的(de)bin目錄下(xià)用∞★♦(yòng)命令行(xíng)來(láiε©)生(shēng)成各種證書(shū)密鑰,在PHP中隻需要(yào)提•λ→ε取密鑰做(zuò)驗證工(gōng)作(zuò)或者加密工(gōnα₽≠g)作(zuò)就(jiù)可(kě)以了(le),密鑰你Ω™(nǐ)隻生(shēng)成一(yī)次嘛,那(n ¶à)個(gè)項目也(yě)不(bù)會(huì)需要(y€ ↓↔ào)你(nǐ)不(bù)停的(de)變密鑰對(duì)是(shì>≥πα)吧(ba).但(dàn)是(shì)你(nǐ)要(y☆✘ào)注意的(de)是(shì)即使在Apache下(xià)使用(​↑<≈yòng)命令行(xíng),你(nǐ)也(yě)需£↔要(yào)一(yī)個(gè)特殊的(dβ₽↑e)openssl.cnf,這(zhè)個(gè)可(kě)以用(yò©‌₩≠ng)于windows環境,你(nǐ)可(kě)以百度一(yī)™♠π下(xià),做(zuò)了(le)這(zhè)些(xiē)工(★α®‍gōng)作(zuò)以後,你(nǐ)可(kě)₽₩♥∑以跟著(zhe)我來(lái)生(shēng£™φ♥)成各種密鑰了(le),假設你(nǐ)在apache/bin目 ↑錄下(xià),所需要(yào)的(de)exr,cnf,dll文(wén✔‍)件(jiàn)都(dōu)拷貝到(dào)這(zhè)個(gè)目錄下(₽©€xià)了(le),然後你(nǐ)打開(kā ✔≈‍i)dos命令行(xíng),進入這(zhè)個(gè)目錄,做(σ​δzuò)以下(xià)工(gōng)作(zuò):

  

生(shēng)成rsa密鑰
openssl genrsa -de ∑s3 -out prikey.pem
去(qù)除掉密鑰文(wén)件(jià£✔↓≥n)保護密碼
openssl rsa -in prikey.pem - ≤out prikey.pem
分(fēn)離(lí)出公鑰
openssl rsa -portant; padding: 0px !important; border-radius'₩÷: 0px !important; border: 0px !important; bottom: auto !imπ♥portant; float: none !important; height: auto !important; left: auto !σ✘∑important; line-height: 1.8em !important; outline: 0pπ↕'x !important; overflow: visible∏≠&≠ !important; position: static ∏©€$!important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-bo∑ ↕♦x !important; font-family: ₹↕β₩Consolas, 'Bitstream Vera ↕♥βSans Mono', 'Courier New', Courier≠©₽₹, monospace !important; min-height: auto !important; color: rgb(0, 0,‍≤φ♣ 255) !important; background: none !imε≈✘≈portant;">in prikey.pem -pubout -out pubkey.pem(獲取證書(shū)中的(de)公鑰×™‌® openssl req -in myreq.pem  -out -pubkey.pe™ε'm)
<β§code class="csharp plain" sty§↑ ♣le="white-space: pre≥γ-wrap; margin: 0px !important; padding: 0px !σ≠important; border-radius: 0px !important; border: 0px !i$♣ δmportant; bottom: auto !important; float: none !important; height: auto !iα 'mportant; left: auto !important; line-height: 1.8e™÷m !important; outline: 0px >♣∑!important; overflow: visible !important; position: static !important; right: auto★≠™€ !important; top: auto !important; vertical-align♥∑: baseline !important; width: auto !important; box-sizing: content-box ‌↔∏!important; font-family: Consolas, 'Bitstr£♠σeam Vera Sans Mono',​&↕ 'Courier New', Courier, monospace !important; min-height: auto !important; color: rgb(0, 0, 0) !i× ®mportant; background: none !important;">對(duì)文(wén)件♥§(jiàn)進行(xíng)簽名
open rsautl -sign♠§β✘ -inkey prikey.pem -in a.txt -out sig.dat
驗證簽名
openssl rsautlφ↑±✔ -verify -inkey prikey.pem -in sig.dat
portant; padding: 0p<♥x !important; border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; outline: 0px !important; overflow: v∞π£&isible !important; position: static !important; right: auto !important; top: auto !important; vertical-al↔δ¶>ign: baseline !important; width: auto !important; box-sizing: c εontent-box !important; font-family: Consolas, 'Bit¶ λ★stream Vera Sans Mono', 'Courier New₹¶∞', Courier, monospace !important; min-height:  ¥β♥auto !important; color: rgb(0, 0, 0) !important; background: none !important;">用(yòng)公鑰對(duì)文(γ€™wén)件(jiàn)加密
openssl rsautl - ¶δ↓encrypt -pubin -inkey α<♦pubkey.pem -in a.text -portant; padding: 0px !important; border-radius: 0÷δpx !important; border: 0px !important; bottom: aut¶δ✔o !important; float: none !important; height: auto !important; left: auto !important; line-height:∑δ 1.8em !important; outline: 0px !important; overflow: visible !∑>important; position: static !important; right: auto !important; top: auto !Ω★∑γimportant; vertical-align: baseline !important; width: auto !important; box-sizing: c±≠ontent-box !important; font-family: Consolas,✔Ωφ₹ 'Bitstream Vera Sans Mono', ↑↕'Courier New', Courier, monospace !important; min-height: auto !important; color: rgb(0, 0, 2γεγ55) !important; background: none !i$£•✘mportant;">out b.text