身份驗(yàn)證技術(shù)方案

身份驗(yàn)證技術(shù)方案


  • 1、身份認(rèn)證流程
    • 1.1 賬號(hào)密碼驗(yàn)證身份
    • 1.2 簽名算法
    • 1.3 數(shù)據(jù)加密
  • 2叠荠、身份認(rèn)證接口
    • 2.1 請(qǐng)求方式
    • 2.2 請(qǐng)求參數(shù)
    • 2.3 數(shù)據(jù)返回
  • 3、附件
    • 3.1 PHP 加解密
    • 3.2 Java 加解密

1扫责、身份認(rèn)證流程

1.1 賬號(hào)密碼驗(yàn)證身份

身份認(rèn)證是其他應(yīng)用的基礎(chǔ)榛鼎,認(rèn)證方(即:校方)需要提供一個(gè)驗(yàn)證接口,具體身份綁定流程如下:


圖片描述

身份認(rèn)證綁定步驟:

  • 學(xué)生在微信客戶端打開(kāi)應(yīng)用鳖孤,觸發(fā)微信公眾號(hào)授權(quán)(授權(quán)頁(yè)面提示授權(quán)給騰訊微校)者娱。
  • 微信公眾號(hào)授權(quán)后,回調(diào)跳轉(zhuǎn)到微校身份綁定頁(yè)面苏揣,輸入校園賬號(hào)(例如學(xué)號(hào))以及相應(yīng)的密碼黄鳍,
  • 微校頁(yè)面數(shù)據(jù)發(fā)送到微校后臺(tái)(注:微校后臺(tái)不會(huì)保存學(xué)生的賬號(hào)和密碼),微校后臺(tái)把對(duì)應(yīng)的信息加密同時(shí)附上簽名發(fā)送到認(rèn)證方的認(rèn)證接口(認(rèn)證方需提供校驗(yàn)接口)平匈。
  • 認(rèn)證方驗(yàn)證簽名框沟、解密,驗(yàn)證學(xué)生身份吐葱,返回加密后的校驗(yàn)結(jié)果街望。
  • 微校收到對(duì)應(yīng)的驗(yàn)證消息,若成功則跳轉(zhuǎn)到對(duì)應(yīng)的應(yīng)用頁(yè)面弟跑,失敗則做出相應(yīng)提示灾前。

1.2 簽名算法

簽名采用微信支付后端簽名算法

1.2.1 簽名生成的通用步驟

設(shè)所有發(fā)送或者接收到的數(shù)據(jù)為集合M,將集合M內(nèi)非空參數(shù)值的參數(shù)按照參數(shù)名ASCII碼從小到大排序(字典序)孟辑,使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)拼接成字符串stringA哎甲。
特別注意以下重要規(guī)則:

  • 參數(shù)名ASCII碼從小到大排序(字典序);
  • 如果參數(shù)的值為空不參與簽名饲嗽;
  • 參數(shù)名區(qū)分大小寫(xiě)炭玫;
  • 驗(yàn)證調(diào)用返回或微信主動(dòng)通知簽名時(shí),傳送的sign參數(shù)不參與簽名貌虾,將生成的簽名與該sign值作校驗(yàn)吞加。

在stringA最后拼接上key得到stringSignTemp字符串,并對(duì)stringSignTemp進(jìn)行MD5運(yùn)算,再將得到的字符串所有字符轉(zhuǎn)換為大寫(xiě)衔憨,得到sign值signValue叶圃。
<br />
簽名算法示例(簽名驗(yàn)證地址):

private static function sign($param_array){
    $names = array_keys($param_array);
    sort($names, SORT_STRING);
    $item_array = array();
    foreach ($names as $name){
        $item_array[] = "{$name}={$param_array[$name]}";
    }
    $secret_key =  APP_SECRET;
    $str = implode('&', $item_array) . '&key=' . APP_KEY;
    return strtoupper(md5($str));
}

1.2.2 APP_KEY & APP_SECRET

由微校生成,每個(gè)公眾號(hào)擁有一對(duì)唯一的APP_KEYAPP_SECRET 践图。
APP_KEYAPP_SECRET 與公眾號(hào)的關(guān)系是一對(duì)一掺冠。也就是說(shuō),不同的公眾號(hào)码党,訪問(wèn)同一個(gè)身份認(rèn)證接口德崭,所用的APP_KEYAPP_SECRET 是不一樣的。

1.3 數(shù)據(jù)加密

采用AES對(duì)稱加密算法(AES/CBC/ZeroPadding 128位模式)揖盘,具體算法見(jiàn)附件。

KEY = APP_KEY
IV = APP_SECRET 前16位扣讼。

2、身份認(rèn)證接口

2.1 請(qǐng)求方式

身份驗(yàn)證接口采用POST的方式向認(rèn)證方發(fā)送數(shù)據(jù)椭符。

2.2 請(qǐng)求參數(shù)

原始數(shù)據(jù) R

{
    "card_num":"3109005843",
    "password":"helloworld",
    "sign":"9A0A8659F005D6984697E2CA0A9CF3B7"http://簽名
}

通過(guò)加密R可以得到R'R' = AES_CBC_ENCRYPT(R)

{
    "raw_data":R',
    "key":APP_KEY
}

微校會(huì)把上面的數(shù)據(jù)以POST的方式發(fā)送到認(rèn)證方提供的認(rèn)證接口销钝。

加密算法見(jiàn)附件。

2.3 數(shù)據(jù)返回

返回?cái)?shù)據(jù):

{
    "code":0,
    "message":"success",
    "raw_data":R',
    "key":APP_KEY
}

關(guān)鍵點(diǎn):

  • 認(rèn)證成功蒸健,認(rèn)證方需保證返回的code 為 0座享。
  • 認(rèn)證失敗,認(rèn)證方需保證返回的code 不為 0似忧。
  • message 字段在 code 不為 0 時(shí)才會(huì)有意義渣叛。
  • key 跟請(qǐng)求時(shí)的 key 保持一致。
  • raw_data 對(duì)應(yīng)的 R' 為加密后的數(shù)據(jù)盯捌。
    通過(guò)解密R' 可得到 RR = AES_CBC_DECRYPT(R·)
{
    "card_num":"07302590", //校園賬號(hào)淳衙,一般是學(xué)號(hào)
    "name":"張三豐", //學(xué)生姓名,必填
    "grade":"2016", //年級(jí)饺著,必填
    "college":"信息科學(xué)與技術(shù)學(xué)院", //學(xué)院
    "profession":"計(jì)算機(jī)系", // 專業(yè)
    "id_card":"4XXX***7", // 身份證號(hào)碼
    "telephone":"137***8", // 手機(jī)號(hào)
    "sign":"9A0A8659F005D6984697E2CA0A9CF3B7"http://簽名
}

其中name箫攀、grade 為必填項(xiàng)。

3幼衰、附件

3.1 PHP 加解密

<?php
class AES
{
    public static function decrypt($str, $key, $iv)
    {
        $decrypt = '';
        for ($i = 0; $i < strlen($str); $i += 2) {
            $decrypt .= chr(hexdec(substr($str, $i, 2)));
        }
        $decrypt = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decrypt, MCRYPT_MODE_CBC, $iv);
        $str = '';
        $decrypt = str_split($decrypt);
        for ($i = 0; $i < count($decrypt); $i++) {
            ord($decrypt[$i]) === 0 or $str .= $decrypt[$i];
        }

        return $str;
    }

    public static function encrypt($str, $key, $iv)
    {
        $encrypt = '';
        $encrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_CBC, $iv);
        $encrypt = bin2hex($encrypt);
        return $encrypt;
    }
}

3.2 Java 加解密

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AES
{
    public static void main(String args[]) throws Exception {
        /**
         * 加密用的Key 可以用26個(gè)字母和數(shù)字組成靴跛,最好不要用保留字符,
         * 雖然不會(huì)錯(cuò)渡嚣,至于怎么裁決梢睛,個(gè)人看情況而定
         *
         * key == AppSecret
         */
        String cKey = "1234567890123456";
        // 需要加密的字串
        String cSrc = "{\"code\":\"0\",\"error_msg\":\"密碼錯(cuò)誤\",\"weixiao_openid\":\"12345678\",\"student_num\":\"888888888888\",\"name\":\"洪丹丹測(cè)試\",\"sign\":\"5C6E844C23C8F0C15AF382081D0663DC\"}";
        // MD5(SHCOOL_ID) 取前16位;
        String cIv = "0123456789123456";
        System.out.println(cSrc);
        // 加密
        long lStart = System.currentTimeMillis();
        String enString = AES.Encrypt(cSrc, cKey, cIv);
        System.out.println("加密后的字串是:" + enString);

        long lUseTime = System.currentTimeMillis() - lStart;
        System.out.println("加密耗時(shí):" + lUseTime + "毫秒");
        // 解密
        lStart = System.currentTimeMillis();
        String DeString = AES.Decrypt(enString, cKey, cIv);
        System.out.println("解密后的字串是:" + DeString);
        lUseTime = System.currentTimeMillis() - lStart;
        System.out.println("解密耗時(shí):" + lUseTime + "毫秒");

    }

    public static String Encrypt(String sSrc, String sKey, String sIv) throws Exception {

        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        int blockSize = cipher.getBlockSize();

        byte[] dataBytes = sSrc.getBytes();
        int plaintextLength = dataBytes.length;
        if (plaintextLength % blockSize != 0) {
            plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
        }

        byte[] plaintext = new byte[plaintextLength];
        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);

        SecretKeySpec keyspec = new SecretKeySpec(sKey.getBytes(), "AES");
        IvParameterSpec ivspec = new IvParameterSpec(sIv.getBytes());

        cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
        byte[] encrypted = cipher.doFinal(plaintext);

        return byte2hex(encrypted).toLowerCase();
    }

    public static String Decrypt(String sSrc, String sKey, String sIv) throws Exception {

        byte[] encrypted1      = hex2byte(sSrc);

        Cipher cipher          = Cipher.getInstance("AES/CBC/NoPadding");
        SecretKeySpec keyspec  = new SecretKeySpec(sKey.getBytes(), "AES");
        IvParameterSpec ivspec = new IvParameterSpec(sIv.getBytes());

        cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

        byte[] original = cipher.doFinal(encrypted1);
        String originalString = new String(original);

        return originalString;
    }

    public static byte[] hex2byte(String strhex) {
        if (strhex == null) {
            return null;
        }
        int l = strhex.length();
        if (l % 2 == 1) {
            return null;
        }
        byte[] b = new byte[l / 2];
        for (int i = 0; i != l / 2; i++) {
            b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
                    16);
        }

        return b;
    }

    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }

        return hs.toUpperCase();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肥印,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绝葡,更是在濱河造成了極大的恐慌竖独,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挤牛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡种蘸,警方通過(guò)查閱死者的電腦和手機(jī)墓赴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)航瞭,“玉大人诫硕,你說(shuō)我怎么就攤上這事】睿” “怎么了章办?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滨彻。 經(jīng)常有香客問(wèn)我藕届,道長(zhǎng),這世上最難降的妖魔是什么亭饵? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任休偶,我火速辦了婚禮,結(jié)果婚禮上踏兜,老公的妹妹穿的比我還像新娘碱妆。我一直安慰自己昔驱,他們只是感情好舍悯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布萌衬。 她就那樣靜靜地躺著秕豫,像睡著了一般观蓄。 火紅的嫁衣襯著肌膚如雪侮穿。 梳的紋絲不亂的頭發(fā)上亲茅,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天克锣,我揣著相機(jī)與錄音袭祟,去河邊找鬼。 笑死捞附,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胆绊。 我是一名探鬼主播辑舷,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼何缓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼碌廓!你這毒婦竟也來(lái)了剩盒?” 一聲冷哼從身側(cè)響起辽聊,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤跟匆,失蹤者是張志新(化名)和其女友劉穎玛臂,沒(méi)想到半個(gè)月后封孙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體虎忌,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膜蠢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年狡蝶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苏章。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泉孩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出寓搬,到底是詐尸還是另有隱情句喷,我是刑警寧澤兔毙,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布澎剥,位于F島的核電站,受9級(jí)特大地震影響祭饭,放射性物質(zhì)發(fā)生泄漏倡蝙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一悠咱、第九天 我趴在偏房一處隱蔽的房頂上張望析既。 院中可真熱鬧眼坏,春花似錦、人聲如沸宰译。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蛛淋,卻和暖如春褐荷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背层宫。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工卒密, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哮奇,地道東北人睛约。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓贸伐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親捉邢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)藐翎,斷路器,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 10,869評(píng)論 6 13
  • Guide to BluetoothSecurity原文 本出版物可免費(fèi)從以下網(wǎng)址獲得:https://doi.o...
    公子小水閱讀 7,907評(píng)論 0 6
  • 1. 實(shí)習(xí)的時(shí)候,因年齡相仿昼扛,和兩個(gè)同事走得比較近。中午一起吃飯抄谐,同事A提議喝奶茶蛹含。B自告奮勇塞颁,收集口味信息后便出...
    寫(xiě)給自己的救贖閱讀 423評(píng)論 0 6
  • 微信里的重聚 13年底祠锣,開(kāi)通了微信,加了很多新老朋友蓬推;原先大學(xué)畢業(yè)后失去聯(lián)系的同學(xué)沸伏、曾經(jīng)的同事糕珊、鄰居红选、友人在朋友圈...
    七點(diǎn)起床閱讀 232評(píng)論 0 1