微信小程序獲取用戶信息锤悄,解密encryptedData

標(biāo)簽:微信小程序 用戶信息
小程序中衣形,通過調(diào)用微信API(wx.getUserInfo)可以或得到當(dāng)前用戶的微信信息(此處會(huì)彈出獲取信息授權(quán)框),但是僅有用戶的基本信息兔院,比如頭像殖卑、昵稱、性別等坊萝,由于產(chǎn)品業(yè)務(wù)需要孵稽,需要得到當(dāng)前用戶的openid以及unionId(微信開放平臺(tái)下用戶的唯一標(biāo)識(shí)),那如何獲仁肌菩鲜?其實(shí)微信的API(wx.getUserInfo)中,已經(jīng)給到這兩組數(shù)據(jù)扯键,只是為了安全睦袖,沒有在明文中顯示珊肃,而是在wx.getUserInfo方法的結(jié)果參數(shù)encryptedData 中荣刑,只要將參數(shù)encryptedData 進(jìn)行解密,就可以得到想要的數(shù)據(jù)伦乔,官方?jīng)]有給到Java的解密過程厉亏,下面是Java版的解密過程:

package com.boboqi.wx.userinfo;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.spec.InvalidParameterSpecException;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import net.sf.json.JSONObject;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Arrays;
import org.codehaus.xfire.util.Base64;
import com.boboqi.wx.common.RemoteInterfaceAddress;
import com.boboqi.wx.util.HttpsClientUtil;
/**
 * 微信小程序信息獲取
 * @author songhn
 */
public class WXAppletUserInfo {
    /**
     * 獲取微信小程序 session_key 和 openid
     */
    public JSONObject getSessionKeyAndOropenid(String code){
        //微信端登錄code值
        String wxCode = code;
        String requestUrl = WxappConfig.GETSESSIONKEYOROPENID;
        Map<String,String> requestUrlParam = new HashMap<String,String>();
        requestUrlParam.put("appid", RemoteInterfaceAddress.AppletAPPID);
        requestUrlParam.put("secret", RemoteInterfaceAddress.AppletAppSecret);
        requestUrlParam.put("js_code", wxCode);
        requestUrlParam.put("grant_type", "authorization_code");
        JSONObject jsonObject = HttpsClientUtil.getInstance().sendGetRequest(requestUrl, requestUrlParam);
        return jsonObject;
    }
    /**
     * 解密用戶敏感數(shù)據(jù)獲取用戶信息
     * @param sessionKey 數(shù)據(jù)進(jìn)行加密簽名的密鑰
     * @param encryptedData 包括敏感數(shù)據(jù)在內(nèi)的完整用戶信息的加密數(shù)據(jù)
     * @param iv 加密算法的初始向量
     */
    public JSONObject getUserInfo(String encryptedData,String sessionKey,String iv){
        // 被加密的數(shù)據(jù)
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘鑰
        byte[] keyByte = Base64.decode(sessionKey);
        // 偏移量
        byte[] ivByte = Base64.decode(iv);
        try {
            // 如果密鑰不足16位,那么就補(bǔ)足.  這個(gè)if 中的內(nèi)容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSONObject.fromObject(result);
            }
        }catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
        return null;
    }
}

附:微信小程序加密數(shù)據(jù)解密算法

接口如果涉及敏感數(shù)據(jù)(如wx.getUserInfo
當(dāng)中的 openId 和unionId )烈和,接口的明文內(nèi)容將不包含這些敏感數(shù)據(jù)爱只。開發(fā)者如需要獲取敏感數(shù)據(jù),需要對(duì)接口返回的加密數(shù)據(jù)( encryptedData )進(jìn)行對(duì)稱解密招刹。 解密算法如下:
對(duì)稱解密使用的算法為 AES-128-CBC恬试,數(shù)據(jù)采用PKCS#7填充。
對(duì)稱解密的目標(biāo)密文為 Base64_Decode(encryptedData)疯暑。
對(duì)稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節(jié)训柴。
對(duì)稱解密算法初始向量 為Base64_Decode(iv),其中iv由數(shù)據(jù)接口返回妇拯。
另外幻馁,為了應(yīng)用能校驗(yàn)數(shù)據(jù)的有效性洗鸵,我們會(huì)在敏感數(shù)據(jù)加上數(shù)據(jù)水印( watermark )

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市仗嗦,隨后出現(xiàn)的幾起案子膘滨,更是在濱河造成了極大的恐慌,老刑警劉巖稀拐,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件火邓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钩蚊,警方通過查閱死者的電腦和手機(jī)贡翘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砰逻,“玉大人鸣驱,你說我怎么就攤上這事◎鹋兀” “怎么了踊东?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)刚操。 經(jīng)常有香客問我闸翅,道長(zhǎng),這世上最難降的妖魔是什么菊霜? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任坚冀,我火速辦了婚禮,結(jié)果婚禮上鉴逞,老公的妹妹穿的比我還像新娘记某。我一直安慰自己,他們只是感情好构捡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布液南。 她就那樣靜靜地躺著,像睡著了一般勾徽。 火紅的嫁衣襯著肌膚如雪滑凉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天喘帚,我揣著相機(jī)與錄音畅姊,去河邊找鬼。 笑死吹由,一個(gè)胖子當(dāng)著我的面吹牛若未,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播溉知,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陨瘩,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼腕够!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舌劳,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤帚湘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后甚淡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體大诸,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年贯卦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了资柔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撵割,死狀恐怖贿堰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啡彬,我是刑警寧澤羹与,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站庶灿,受9級(jí)特大地震影響纵搁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜往踢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一腾誉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧峻呕,春花似錦利职、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽英支。三九已至佩憾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間干花,已是汗流浹背妄帘。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留池凄,地道東北人抡驼。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肿仑,于是被迫代替她去往敵國(guó)和親致盟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子碎税,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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