微信企業付款介面PHP開發需要注意的兩個地方

一隻小夥伴發表於2018-06-03

curl擴充

  • curl_setopt($ch, CURLOPT_SSLCERT, getcwd().'/cert/mycert.pem');

在做微信支付介面雙向驗證的時候,需要pem證照檔案,然而在Mac上做本地測試的時候一直返回curl 58錯誤,經過一番查閱,發現,php的curl擴充在Mac和linux上是不大一樣的兩者的協議棧不一樣

Mac下的協議棧是Secure Transport 而ubuntu下的協議棧是 openssl (據說centos也有這個問題)

openssl函式

在獲取到微信返回的rsa公鑰字串後,需要通過phpopenssl_public_encrypt()函式對資料進行公鑰加密,然而拿到的rsa公鑰字串卻無法直接用openssl_get_publickey()來獲取其中的公鑰,我第一反應以為是格式(空格換行符)等原因造成的,調了一下午之後終於發現了端倪,仔細看這個獲取公鑰的函式,官方是這麼介紹的

an X.509 certificate resource
a string having the format file://path/to/file.pem. The named file must contain a PEM encoded certificate/public key (it may contain both).
A PEM formatted public key.
複製程式碼

注意一下這個X.509,這個函式是以這個風格載入public key的,而微信給我們的是公鑰是PKCS#1 RSA public key,因此不能直接載入,總是返回false 而評論區告訴了我們思路與具體實現

思路如下

If you are trying to read a PKCS#1 RSA public key you run into trouble, because openssl wants the public key in X.509 style.

The PKCS#1 RSA public key

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAgYxTW5Yj+5QiQtlPMnS9kqQ/HVp+T2KtmvShe68cm8luR7Dampmb
[...]
cbn6n2FsV91BlEnrAKq65PGJxcwcH5+aJwIDAQAB
-----END RSA PUBLIC KEY-----

.. is  not readable while the X.509 style public key

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgYxTW5Yj+5QiQtlPMnS9
[..]
JwIDAQAB
-----END PUBLIC KEY-----

is. You can use an easy (and dirty) work around to read the PKCS#1 RSA anyway. The first few bytes of the X.509 style public key contain header information and can shamelessly be copied.

In other words: Delete everything after the first 32 bytes from the above X.509 key (starting behind Q8A) and attach your PKCS#1 data, reformat to 64 bytes length and use it with openssl.

Please note: The above example only works for 2048 bit length.

Like I said - it's kind of dirty - but hey - if you're as desperate as I was.

Michaela
複製程式碼

具體實現如下

// Michaela code retranscription can be :

$key = str_replace([
    '-----BEGIN RSA PUBLIC KEY-----',
    '-----END RSA PUBLIC KEY-----',
    "\r\n",
    "\n",
], [
    '',
    '',
    "\n",
    ''
], $key);

$key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A' . trim($key);

$key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
複製程式碼

當然了,如果你想像微信官方介紹的那樣,讓檔案落地,一勞永逸,可以用openssl rsa -RSAPublicKey_in -in <filename> -pubout將PKCS#1標準的RSA公鑰pem檔案轉換為PKCS#8標準的檔案,道理是一樣的

相關文章