C#實現微信AES-128-CBC加密數據的解密


 

小程序登錄時,獲得用戶的信息,只是昵稱,無法用作ID。而有用的數據,都加密着,騰訊給出了解密的方法:

 

加密數據解密算法

接口如果涉及敏感數據(如wx.getUserInfo當中的 openId 和unionId ),接口的明文內容將不包含這些敏感數據。開發者如需要獲取敏感數據,需要對接口返回的加密數據( encryptedData )進行對稱解密。 解密算法如下:

  1. 對稱解密使用的算法為 AES-128-CBC,數據采用PKCS#7填充。
  2. 對稱解密的目標密文為 Base64_Decode(encryptedData),
  3. 對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節
  4. 對稱解密算法初始向量 iv 會在數據接口中返回。

微信官方提供了多種編程語言的示例代碼(點擊下載)。每種語言類型的接口名字均一致。調用方式可以參照示例。

 

下載示例代碼,沒有C#的,只有C++、nodejs、python、php的,頓時受到巨大的打擊。在網上找C#的AES-128-CBC算法,就沒有一個好用的,下載下來半天調不通,看看nodejs和python的代碼,簡單到令人發指,頓時讓我的信心再次遭受打擊。

image

想想,如果單獨為解密搭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;

    }
}

實在搞不通騰訊干嘛這么折騰。。。

 


我的小程序:簡單賬本


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM