新聞中心
- 用戶(hù)數(shù)據(jù)的簽名驗(yàn)證和加解密
- 開(kāi)放數(shù)據(jù)說(shuō)明
- 開(kāi)發(fā)者后臺(tái)校驗(yàn)與解密開(kāi)放數(shù)據(jù)
- 解密算法說(shuō)明
- 會(huì)話(huà)密鑰 session_key 有效性說(shuō)明
- 解密后內(nèi)容
- 解密示例代碼
- 涉及加解密的開(kāi)放數(shù)據(jù)接口
- 解密常見(jiàn)問(wèn)題
用戶(hù)數(shù)據(jù)的簽名驗(yàn)證和加解密
開(kāi)放數(shù)據(jù)說(shuō)明
智能小程序可以通過(guò)各種前端接口獲取百度提供的開(kāi)放數(shù)據(jù)。為了確保開(kāi)放接口返回用戶(hù)數(shù)據(jù)的安全性,百度會(huì)對(duì)這些數(shù)據(jù)做簽名和加密處理。開(kāi)發(fā)者后臺(tái)拿到開(kāi)放數(shù)據(jù)后可以對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)簽名和解密。

開(kāi)發(fā)者后臺(tái)校驗(yàn)與解密開(kāi)放數(shù)據(jù)
接口如果涉及敏感數(shù)據(jù),接口的明文內(nèi)容將不包含這些敏感數(shù)據(jù)。開(kāi)發(fā)者如需要獲取敏感數(shù)據(jù),需要對(duì)接口返回的加密數(shù)據(jù)(data)進(jìn)行對(duì)稱(chēng)解密。
解密過(guò)程:開(kāi)發(fā)者智能小程序(通過(guò) swan.request)將加密數(shù)據(jù)發(fā)送至自身 Server 進(jìn)行解密后返回智能小程序。
解密算法說(shuō)明
- 對(duì)稱(chēng)解密使用的算法為 AES-192-CBC,數(shù)據(jù)采用 PKCS#7 填充;
- 對(duì)稱(chēng)解密的目標(biāo)密文為 Base64_Decode(data);
- 對(duì)稱(chēng)解密秘鑰 AESKey = Base64_Decode(session_key),AESKey 是 24 字節(jié);
- 對(duì)稱(chēng)解密算法初始向量 為 Base64_Decode(iv),其中 iv 由數(shù)據(jù)接口返回。
會(huì)話(huà)密鑰 session_key 有效性說(shuō)明
基于 session_key 的開(kāi)發(fā)者請(qǐng)關(guān)注下面幾個(gè)與 session_key 有關(guān)的注意事項(xiàng):
1、 session_key 是具有時(shí)效性的,過(guò)期的 sessionn_key 將無(wú)法使用。開(kāi)發(fā)者在 session_key 失效時(shí),需要通過(guò)重新執(zhí)行登錄流程獲取session_key。
2、 使用 checkSession() 可以校驗(yàn) Session Key 是否有效,從而避免小程序反復(fù)執(zhí)行登錄流程,參考授權(quán)流程圖中 checkSession() 使用。
3、 智能小程序不會(huì)把 session_key 的有效期告知開(kāi)發(fā)者。我們會(huì)根據(jù)用戶(hù)使用小程序的行為對(duì) session_key 進(jìn)行續(xù)期。用戶(hù)越頻繁使用小程序, session_key 有效期越長(zhǎng)。
注意
session_key過(guò)期會(huì)導(dǎo)致開(kāi)放數(shù)據(jù)解密失敗。要判斷當(dāng)前用戶(hù)的授權(quán)會(huì)話(huà)是否仍處于有效期,可調(diào)用 swan.checkSession() 方法進(jìn)行判斷,詳情參照登錄授權(quán)流程說(shuō)明。
解密后內(nèi)容
| 內(nèi)容 | 長(zhǎng)度 |
|---|---|
| 隨機(jī)填充內(nèi)容 | 16 字節(jié) |
| 用戶(hù)數(shù)據(jù)長(zhǎng)度 | 4 字節(jié),大端序無(wú)符號(hào) 32 位整型 |
| 用戶(hù)數(shù)據(jù) | 由用戶(hù)數(shù)據(jù)長(zhǎng)度描述 |
| app_key | 與 app_key 長(zhǎng)度相同 |
解密示例代碼
特別說(shuō)明:受美國(guó)軟件出口限制,JDK 默認(rèn)使用的 AES 算法最高只能支持 128 位。如需要更高位的支持需要從 oracle 官網(wǎng)下載 Java 密碼技術(shù)擴(kuò)展(JCE)更換 JAVA_HOME/jre/lib/security 目錄下的: local_policy.jar 和 US_export_policy.jar。
下載地址:https://www.oracle.com/technetwork/java/javase/downloads/jce-all-download-5170447.html
- PHP 版本
- JAVA 版本
/*** @Author: [email protected]* Copyright 2018 The BAIDU. All rights reserved.** 百度小程序用戶(hù)信息加解密示例代碼(面向過(guò)程版)* 示例代碼未做異常判斷,請(qǐng)勿用于生產(chǎn)環(huán)境*/function test() {$app_key = 'y2dTfnWfkx2OXttMEMWlGHoB1KzMogm7';$session_key = '1df09d0a1677dd72b8325aec59576e0c';$iv = "1df09d0a1677dd72b8325Q==";$ciphertext = "OpCoJgs7RrVgaMNDixIvaCIyV2SFDBNLivgkVqtzq2GC10egsn+PKmQ/+5q+chT8xzldLUog2haTItyIkKyvzvmXonBQLIMeq54axAu9c3KG8IhpFD6+ymHocmx07ZKi7eED3t0KyIxJgRNSDkFk5RV1ZP2mSWa7ZgCXXcAbP0RsiUcvhcJfrSwlpsm0E1YJzKpYy429xrEEGvK+gfL+Cw==";$plaintext = decrypt($ciphertext, $iv, $app_key, $session_key);// 解密結(jié)果應(yīng)該是 '{"openid":"open_id","nickname":"baidu_user","headimgurl":"url of image","sex":1}'echo $plaintext, PHP_EOL;}test();/*** 數(shù)據(jù)解密:低版本使用mcrypt庫(kù)(PHP < 5.3.0),高版本使用openssl庫(kù)(PHP >= 5.3.0)。** @param string $ciphertext 待解密數(shù)據(jù),返回的內(nèi)容中的data字段* @param string $iv 加密向量,返回的內(nèi)容中的iv字段* @param string $app_key 創(chuàng)建小程序時(shí)生成的app_key* @param string $session_key 登錄的code換得的* @return string | false*/function decrypt($ciphertext, $iv, $app_key, $session_key) {$session_key = base64_decode($session_key);$iv = base64_decode($iv);$ciphertext = base64_decode($ciphertext);$plaintext = false;if (function_exists("openssl_decrypt")) {$plaintext = openssl_decrypt($ciphertext, "AES-192-CBC", $session_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);} else {$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, null, MCRYPT_MODE_CBC, null);mcrypt_generic_init($td, $session_key, $iv);$plaintext = mdecrypt_generic($td, $ciphertext);mcrypt_generic_deinit($td);mcrypt_module_close($td);}if ($plaintext == false) {return false;}// trim pkcs#7 padding$pad = ord(substr($plaintext, -1));$pad = ($pad < 1 || $pad > 32) ? 0 : $pad;$plaintext = substr($plaintext, 0, strlen($plaintext) - $pad);// trim header$plaintext = substr($plaintext, 16);// get content length$unpack = unpack("Nlen/", substr($plaintext, 0, 4));// get content$content = substr($plaintext, 4, $unpack['len']);// get app_key$app_key_decode = substr($plaintext, $unpack['len'] + 4);return $app_key == $app_key_decode ? $content : false;}
/** Copyright (C) 2018 Baidu, Inc. All Rights Reserved.*//** Copyright (C) 2018 Baidu, Inc. All Rights Reserved.*/package com.baidu.utils.secruity;import java.nio.charset.Charset;import java.util.Arrays;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import org.apache.commons.codec.binary.Base64;public class Demo {private static Charset CHARSET = Charset.forName("utf-8");/*** 對(duì)密文進(jìn)行解密** @param text 需要解密的密文** @return 解密得到的明文** @throws Exception 異常錯(cuò)誤信息*/public String decrypt(String text, String sessionKey,String ivStr) throws Exception {byte[] aesKey = Base64.decodeBase64(sessionKey + "=");byte[] original;try {Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");byte[] ivBytes = Base64.decodeBase64(ivStr);IvParameterSpec iv = new IvParameterSpec(ivBytes);cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);byte[] encrypted = Base64.decodeBase64(text);original = cipher.doFinal(encrypted);} catch (Exception e) {throw new Exception(e);}String xmlContent;String fromClientId;try {// 去除補(bǔ)位字符byte[] bytes = PKCS7Encoder.decode(original);// 分離16位隨機(jī)字符串,網(wǎng)絡(luò)字節(jié)序和ClientIdbyte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);int xmlLength = recoverNetworkBytesOrder(networkOrder);xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);fromClientId = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);} catch (Exception e) {throw new Exception(e);}return xmlContent;}public static String getType(Object test) {return test.getClass().getName().toString();}/*** 還原4個(gè)字節(jié)的網(wǎng)絡(luò)字節(jié)序** @param orderBytes 字節(jié)碼** @return sourceNumber*/private int recoverNetworkBytesOrder(byte[] orderBytes) {int sourceNumber = 0;int length = 4;int number = 8;for (int i = 0; i < length; i++) {sourceNumber <<= number;sourceNumber |= orderBytes[i] & 0xff;}return sourceNumber;}/*** 加密解密demo** @param args* @throws Exception*/public static void main(String[] args) throws Exception {String dy = "toMIrTrp2WovaM4RUoqsrBX4kR7p5JThrzY8bW4ZTBKm4YPRr0CfxY8ZZFwk0RJIPEVCVNebRuN3h6zOIHrHrjdvz5hcKkRfX3VO4OfoHJ3LiZv5uVRl6056iLBgNm+x2HY6T07A40aKeYJQDT3kmgdaAi3UB7NUlrEFUpAuZ2Tsm5B+bF3lnbmUzhskTCFE";String sessionKey = "a28bea08d86e426f8d51e024194eae6f";String iv = "a28bea08d86e426f8d51ew==";Demo demo = new Demo();String dd = demo.decrypt(dy, sessionKey, iv);System.out.println(dd);}}class PKCS7Encoder {static Charset CHARSET = Charset.forName("utf-8");static int BLOCK_SIZE = 32;/*** 獲得對(duì)明文進(jìn)行補(bǔ)位填充的字節(jié).** @param count 需要進(jìn)行填充補(bǔ)位操作的明文字節(jié)個(gè)數(shù)** @return 補(bǔ)齊用的字節(jié)數(shù)組*/static byte[] encode(int count) {// 計(jì)算需要填充的位數(shù)int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);if (amountToPad == 0) {amountToPad = BLOCK_SIZE;}// 獲得補(bǔ)位所用的字符char padChr = chr(amountToPad);String tmp = new String();for (int index = 0; index < amountToPad; index++) {tmp += padChr;}return tmp.getBytes(CHARSET);}/*** 刪除解密后明文的補(bǔ)位字符** @param decrypted 解密后的明文** @return 刪除補(bǔ)位字符后的明文*/static byte[] decode(byte[] decrypted) {int pad = (int) decrypted[decrypted.length - 1];if (pad < 1 || pad > 32) {pad = 0;}return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);}/*** 將數(shù)字轉(zhuǎn)化成ASCII碼對(duì)應(yīng)的字符,用于對(duì)明文進(jìn)行補(bǔ)碼** @param a 需要轉(zhuǎn)化的數(shù)字** @return 轉(zhuǎn)化得到的字符*/static char chr(int a) {byte target = (byte) (a & 0xFF);return (char) target;}}
涉及加解密的開(kāi)放數(shù)據(jù)接口
各場(chǎng)景解密獲取的數(shù)據(jù)結(jié)構(gòu)請(qǐng)參照相應(yīng)功能的接口文檔說(shuō)明
獲取用戶(hù)信息 - button 組件方式、獲取用戶(hù)手機(jī)號(hào)
解密常見(jiàn)問(wèn)題
java 解密報(bào) OOM 錯(cuò)誤解決辦法:受美國(guó)軟件出口限制,JDK 默認(rèn)使用的 AES 算法最高只能支持 128 位。如需要更高位的支持需要從 oracle 官網(wǎng)下載 Java 密碼技術(shù)擴(kuò)展(JCE)更換 JAVA_HOME/jre/lib/security 目錄下的:local_policy.jar 和 US_export_policy.jar。
下載地址:https://www.oracle.com/technetwork/java/javase/downloads/jce-all-download-5170447.html
網(wǎng)站欄目:創(chuàng)新互聯(lián)百度小程序教程:用戶(hù)數(shù)據(jù)的簽名驗(yàn)證和加解密
標(biāo)題路徑:http://m.fisionsoft.com.cn/article/dhsocih.html


咨詢(xún)
建站咨詢(xún)
