国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【渣渣程序員踩過的坑】PHP的hash_hmac簽名加密,PHP迷一樣的base64_encode

henry14 / 3936人閱讀

摘要:如何獲取受支持的算法清單,請(qǐng)參見。要進(jìn)行哈希運(yùn)算的消息。使用生成信息摘要時(shí)所使用的密鑰。設(shè)置為輸出原始二進(jìn)制數(shù)據(jù),設(shè)置為輸出小寫進(jìn)制字符串。

介紹一下問題的背景:

本人一枚小小PHPer,有一天公司的Java找到我,讓我?guī)兔懸粋€(gè)接口的Demo,心想:‘最喜歡寫接口了,來來來來!’,于是Java就帶著Java版Demo來了,大概看了一遍,具體涉及以下幾點(diǎn):(不想了解的看最后一部分,就好了,那是中心思想)

md5加密:

java中定義hashMap,儲(chǔ)存userid,再使用toJSONString將其轉(zhuǎn)換成Json串,再將Json使用md5Hex加密,再放入hashMap中

map參數(shù)格式轉(zhuǎn)換:

將map中的數(shù)據(jù)轉(zhuǎn)換成String,對(duì)key,value進(jìn)行數(shù)據(jù)拼接,拼接成字符串,此字符串具體要求如下:
‘按照參數(shù)名ASCII碼從小到大排序,使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)構(gòu)造成字符串signPlainText’

hash_hmac簽名驗(yàn)證:

這個(gè)沒什么說的,PHP中有hash_hmac函數(shù)

談?wù)撘幌掠龅降目樱?/b>

本PHPer比較渣渣,不知道Java中的hashMap是用來做啥的,但我知道,它最后做了一件事:JSONObject.toJSONString(body),沒錯(cuò),轉(zhuǎn)換成字符串了,所以有了以下代碼:(不負(fù)責(zé)的貼圖,不知道正確與否)

md5加密

Java版

            Map body = new HashMap<>();
            body.put("userId", userId);
            //post請(qǐng)求body為json格式,將json格式進(jìn)行md5加密
            String postBody = JSONObject.toJSONString(body);
            String bodyMd = DigestUtils.md5Hex(postBody);

PHP版

            $body = ["userId"=>$userId];
            $postbody = json_encode($body);
            $bodyMd = md5($postbody);

上邊我們之間應(yīng)該是在做一件事請(qǐng)吧?應(yīng)該是的,反正都是轉(zhuǎn)成了Json,轉(zhuǎn)成了Md5

接下來就是map轉(zhuǎn)換string了,再貼兩段代碼:(不負(fù)責(zé)的貼,不知道正確與否)
(按照參數(shù)名ASCII碼從小到大排序,使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)構(gòu)造成字符串signPlainText)

map參數(shù)格式轉(zhuǎn)換:

Java版

        Map resultMap = new TreeMap<>();
        for (Map.Entry entry : map.entrySet()) {
            String key = (String) entry.getKey();
            Object value = entry.getValue();
            if (StringUtils.isEmpty(key) || value == null) {
                continue;
            }
            resultMap.put(key, value);
        }
        StringBuilder buff = new StringBuilder();
        for (Map.Entry entry : resultMap.entrySet()) {
            buff.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        String signPlanText = buff.toString();
        if (StringUtils.isNotEmpty(signPlanText)) {
            signPlanText = signPlanText.substring(0, signPlanText.length() - 1);
        }
        return signPlanText;

PHP版

        $signPlanText = "";
        ksort($params);
        foreach ($params as $key => $param){
            if(empty($key) || $param == null){
                continue;
            }
            $signPlanText .= $key."=".$param."&";
        }
        if($signPlanText){
            $signPlanText = substr($signPlanText,0,strlen($signPlanText)-1);
        }
        return $signPlanText;

遇到的問題: 因?yàn)镴ava中Treemap是有序的,按照自然值進(jìn)行排序,但PHP中好像沒有這樣一個(gè)東西,所以決定使用Ksort來進(jìn)行排序,不知道是否正確!應(yīng)該是正確的吧?各位大神拍磚~

HmacSHA256簽名驗(yàn)證:

Java版

        String signature = "";
        try {
            Mac sha256HMAC = Mac.getInstance(HMACSHA256);
            SecretKeySpec secretkey = new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), HMACSHA256);
            sha256HMAC.init(secretkey);
            byte[] bytes = sha256HMAC.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            signature = Base64.encodeBase64URLSafeString(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return signature;

PHP版( 呀?看起來是不是沒有問題?)

        $hmac_sha256_str = base64_encode(hash_hmac("sha256", $signPlanText, $appSecret));
        $signature = urlencode($hmac_sha256_str);
        return $signature;

還在想,PHP這么點(diǎn)代碼就解決了?不愧是世界上最好的語言’,(大佬們,我加引號(hào)了)
23:35分終于翻譯完以上Java代碼,放一首歌,美美的睡覺,心想明天可以美美的交工~ (滴滴滴滴滴滴等待~地理地理等待~~)

坑來了,運(yùn)行上邊代碼,你會(huì)發(fā)現(xiàn),接口提示簽名錯(cuò)誤!!錯(cuò)誤一直是錯(cuò)誤!!為什么呢???明明是一樣的啊!百思不得其解!!

繼續(xù)往下看···

再看PHP文檔中的hash_hmac的聲明:

string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = FALSE ] )

algo
要使用的哈希算法名稱,例如:"md5","sha256","haval160,4" 等。 如何獲取受支持的算法清單,請(qǐng)參見 hash_algos()。

data
要進(jìn)行哈希運(yùn)算的消息。

key
使用 HMAC 生成信息摘要時(shí)所使用的密鑰。

raw_output 設(shè)置為 TRUE 輸出原始二進(jìn)制數(shù)據(jù), 設(shè)置為 FALSE 輸出小寫 16 進(jìn)制字符串。

在Java中sha256HMAC后得到的值為二進(jìn)制,So,PHP也要轉(zhuǎn)換為二進(jìn)制,所以改進(jìn)為以下代碼:

        hash_hmac("sha256", $signPlanText, $appSecret,true);//由此生成出的為二進(jìn)制格式

這還沒完,最重要的出現(xiàn)了:

java中Base64.encodeBase64URLSafeString(bytes) 會(huì)將 特殊字符‘+/’替換為"-_",會(huì)將‘=’去掉

但是!!PHP不會(huì)!!! PHP 沒有提供url安全的base64編碼函數(shù),需要自己手動(dòng)去擼!還是自己水平不夠

So,出現(xiàn)了以下代碼,也是最終的解決方案:

     /**
     * 簽名驗(yàn)證
     */
    public static function generateSHASign($signPlanText,$appSecret){
        $signature = self::base64UrlEncode(hash_hmac("sha256",$signPlanText, $appSecret, true));
        return $signature;
    }

    /**
     * 替換特殊符號(hào)
     */
    public static function base64UrlEncode($str){
       return rtrim(strtr(base64_encode($str),"+/","-_"),"=");
    }

這時(shí),你會(huì)發(fā)現(xiàn),簽名正確,原來生活如此美好、怪我太年輕


同時(shí)有朋友說:
1.是有兩套不相同的標(biāo)準(zhǔn),Ios一套,Java一套
2.在PHP中url_encode這個(gè)函數(shù),分兩種: urlencode 和 rawurlencode

兩者的差異:urlencode和rawurlencode兩個(gè)方法在處理字母數(shù)字,特殊符號(hào),中文的時(shí)候結(jié)果都是一樣的,唯一的不同是對(duì)空格的處理,urlencode處理成“+”,rawurlencode處理成%20

總結(jié)下來就是:

php的base64_encode和base64_decode用來轉(zhuǎn)換url是不符合要求,所以需要自己實(shí)現(xiàn)方法

base64url_decode

    public static function base64url_decode($data)
    {
        return base64_decode(str_pad(strtr($data, "-_", "+/"), strlen($data) % 4, "=", STR_PAD_RIGHT));
    }

base64url_encode

    public static function base64url_encode($data)
    {
        return rtrim(strtr(base64_encode($data), "+/", "-_"), "=");
    }

終是曉夢(mèng)迷了蝶,你是恩賜也是劫!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/30011.html

相關(guān)文章

  • 渣渣序員踩過PHPhash_hmac簽名加密PHP一樣base64_encode

    摘要:如何獲取受支持的算法清單,請(qǐng)參見。要進(jìn)行哈希運(yùn)算的消息。使用生成信息摘要時(shí)所使用的密鑰。設(shè)置為輸出原始二進(jìn)制數(shù)據(jù),設(shè)置為輸出小寫進(jìn)制字符串。 介紹一下問題的背景: 本人一枚小小PHPer,有一天公司的Java找到我,讓我?guī)兔懸粋€(gè)接口的Demo,心想:‘最喜歡寫接口了,來來來來!’,于是Java就帶著Java版Demo來了,大概看了一遍,具體涉及以下幾點(diǎn):(不想了解的看最后一部分,就好...

    Rocture 評(píng)論0 收藏0
  • 帶你弄懂JWT原理

    摘要:的組成一個(gè)實(shí)際上就是一個(gè)字符串,它由三部分組成,頭部載荷與簽名。這個(gè)字符串我們將它稱作的載荷。注意是一種編碼,它是可以被翻譯回原來的樣子來的。這也可以被表示成一個(gè)對(duì)象。 JSON Web Token(JWT)是一個(gè)非常輕巧的規(guī)范。這個(gè)規(guī)范允許我們使用JWT在用戶和服務(wù)器之間傳遞安全可靠的信息。 讓我們來假想一下一個(gè)場(chǎng)景。在A用戶關(guān)注了B用戶的時(shí)候,系統(tǒng)發(fā)郵件給B用戶,并且附有一個(gè)鏈接點(diǎn)...

    animabear 評(píng)論0 收藏0
  • yii2加密解密那些事兒

    摘要:我們做程序的時(shí)候,加密解密是繞不開的話題,使用開發(fā)應(yīng)用的時(shí)候,都內(nèi)置了哪些有關(guān)加密解密安全方便的支持那本文將為你揭曉。函數(shù)聲明為存在著第三個(gè)參數(shù),比如我們可以傳遞會(huì)員的等,這樣此信息將和一起作為加密解密的鑰匙。 我們做程序的時(shí)候,加密解密是繞不開的話題,使用yii2開發(fā)應(yīng)用的時(shí)候,都內(nèi)置了哪些有關(guān)加密解密(安全)方便的支持那?本文將為你揭曉。 相關(guān)環(huán)境 操作系統(tǒng)及IDE macOS ...

    dendoink 評(píng)論0 收藏0
  • PHP hash 接口對(duì)接

    摘要:另外說到請(qǐng)求對(duì)方接口的問題,對(duì)方要求傳遞一個(gè)參數(shù)過去,比如結(jié)果提示但是沒問題于是對(duì)參數(shù)再進(jìn)行一次但對(duì)方有時(shí)候接受的參數(shù)解析出錯(cuò)于是有了如下處理傳遞時(shí)也改成安全 最近接一個(gè)項(xiàng)目,需要調(diào)用對(duì)方接口生成 token 但只提供了 node 版,源代碼如下 //https://blog.zhengxianjun.com/2015/05/javascript-crypto-js/ npm inst...

    kel 評(píng)論0 收藏0
  • PHP里使用ImageMagick生成base64圖片

    摘要:個(gè)人博客本文原地址最近的項(xiàng)目中,需要用到畫圖和圖片拼接效果,這里是一些開發(fā)過程里用到的一些點(diǎn)還有就是一些踩過的坑。通過生成圖片格式,為前端所使用。需要注意的是前端得到的額數(shù)據(jù)里包含有回車字符,需要特殊處理才可以正確顯示圖片。 個(gè)人博客 https://duanruilong.github.io/blog/本文原地址https://duanruilong.github.io/blog/2...

    avwu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<