小程序登錄時,獲得用戶的信息,只是昵稱,無法用作ID。而有用的數據,都加密着,騰訊給出了解密的方法:
加密數據解密算法
接口如果涉及敏感數據(如wx.getUserInfo
當中的 openId 和unionId ),接口的明文內容將不包含這些敏感數據。開發者如需要獲取敏感數據,需要對接口返回的加密數據( encryptedData )進行對稱解密。 解密算法如下:
- 對稱解密使用的算法為 AES-128-CBC,數據采用PKCS#7填充。
- 對稱解密的目標密文為 Base64_Decode(encryptedData),
- 對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節
- 對稱解密算法初始向量 iv 會在數據接口中返回。
微信官方提供了多種編程語言的示例代碼(點擊下載)。每種語言類型的接口名字均一致。調用方式可以參照示例。
下載示例代碼,沒有C#的,只有C++、nodejs、python、php的,頓時受到巨大的打擊。在網上找C#的AES-128-CBC算法,就沒有一個好用的,下載下來半天調不通,看看nodejs和python的代碼,簡單到令人發指,頓時讓我的信心再次遭受打擊。
想想,如果單獨為解密搭nodejs或者python實在不值得,咬牙繼續研究.Net下的解密,最有用的來自csdn,感謝作者
http://download.csdn.net/detail/u010331683/5798913
但是,還是無法正常使用,分析原因跟轉碼有關系,微信示例中是用base64來存儲密文、密鑰和向量的,但C#示例是用utf8,經過一番痛苦的調試,終於搞定,把用到的代碼直接粘貼過來:
調用代碼:
AESHelper.AesIV = "r7BXXKkLb8qrSNn05n0qiA=="; AESHelper.AesKey = "tiihtNczf5v6AKRyjwEUhQ=="; string text = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM" + "QmRzooG2xrDcvSnxIMXFufNstNGTyaGS" + "9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+" + "3hVbJSRgv+4lGOETKUQz6OYStslQ142d" + "NCuabNPGBzlooOmB231qMM85d2/fV6Ch" + "evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6" + "/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw" + "u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn" + "/Hz7saL8xz+W//FRAUid1OksQaQx4CMs" + "8LOddcQhULW4ucetDf96JcR3g0gfRK4P" + "C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB" + "6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns" + "/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd" + "lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV" + "oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG" + "20f0a04COwfneQAGGwd5oa+T8yO5hzuy" + "Db/XcxxmK01EpqOyuxINew=="; string s = AESHelper.AESDecrypt(text);
改過的解碼部分,我直接把base64的字符串傳遞進去,在里面解開:
public static string AESDecrypt(string text) { try { //判斷是否是16位 如果不夠補0 //text = tests(text); //16進制數據轉換成byte byte[] encryptedData =Convert.FromBase64String(text); // strToToHexByte(text); RijndaelManaged rijndaelCipher = new RijndaelManaged(); rijndaelCipher.Key =Convert.FromBase64String(AesKey); // Encoding.UTF8.GetBytes(AesKey); rijndaelCipher.IV = Convert.FromBase64String(AesIV);// Encoding.UTF8.GetBytes(AesIV); rijndaelCipher.Mode = CipherMode.CBC; rijndaelCipher.Padding = PaddingMode.PKCS7; ICryptoTransform transform = rijndaelCipher.CreateDecryptor(); byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length); string result = Encoding.Default.GetString(plainText); //int index = result.LastIndexOf('>'); //result = result.Remove(index + 1); return result; } catch (Exception ex) { return null; } }
實在搞不通騰訊干嘛這么折騰。。。
我的小程序:簡單賬本