* 2014.08.02 update *
If you need a python code right away, then please keep in touch with https://github.com/carpedm20/LINE
Finally, I want to talk about session key and auth key.
5. Session key
At first, I tried to follow UpdateAuthToken() function because this function adds the "X-Line-Access" header to the HTTP protocol.
As I followed this function, I finally arrived to create() function which updates the old session key.
It wasn't hard to understand how this function updates authKey, but I couldn't figure out when LINE change an auth key.
It seems like LINE's session key is changed when a user change his/her mobile phone or re-install the application.
In other words, the session key won't be changed if you don't erase or change your mobile phone.
This can cause security problems if someone change the code of LINE application and distribute it to the internet...but I don't think it will happen :)
Bellow is the list of functions that I followed to find out how LINE update their authorization key.
- public void UpdateAuthToken(string authKey)
- {
- if (authKey != null)
- {
- this._transport.AddRequestHeader("X-Line-Access", AccessTokenHelper.GetAccessToken(authKey)); // add "X-Line-Access" header to HTTP(s) protocol
- }
- }
- public void UpdateAuthToken(string authKey)
- {
- try
- {
- if (authKey != null)
- {
- this._transport.AddRequestHeader("X-Line-Access", AccessTokenHelper.GetAccessToken(authKey)); // add "X-Line-Access" header to HTTP(s) protocol
- }
- }
- catch (Exception)
- {
- }
- }
- private void _addCustomHeader(HttpWebRequest httpWebRequest)
- {
- Profile current = ProfileViewModel.GetInstance().Current;
- httpWebRequest.get_Headers().set_Item("X-Line-Access", AccessTokenHelper.GetAccessToken(current.AuthKey)); // add "X-Line-Access" header to HTTP(s) protocol
- httpWebRequest.get_Headers().set_Item("X-Line-Application", DeviceUtility.GetLineApplicationString());
- httpWebRequest.get_Headers().set_Item("Cache-Control", "no-cache");
- httpWebRequest.get_Headers().set_Item("Pragma", "no-cache");
- }
- public static string GetAccessToken(string authKey)
- {
- long timestamp = (DateTime.get_UtcNow() - new DateTime(0x7b2, 1, 1, 0, 0, 0, 1)).get_TotalMilliseconds(); // use time stamp for making access token
- return GetAccessToken(timestamp, authKey);
- }
- public static string GetAccessToken(long timestamp, string authKey)
- {
- if (((_accessToken == "") || !_accessToken.Equals(_lastAuthToken)) || (timestamp > (_lastUpdated + 0x5265c00L)))
- {
- lock (_thisLock)
- {
- _accessToken = Generate(authKey, timestamp);
- _lastUpdated = timestamp;
- _lastAuthToken = authKey;
- }
- }
- return _accessToken;
- }
- public static string Generate(string authToken, long timestamp)
- {
- string[] strArray = authToken.Split(new char[] { ':' });
- if (strArray.Length != 2)
- {
- throw new ArgumentException("authToken");
- }
- string issueTo = strArray[0]; // use previous authToken for the new authToken
- string encodedSecretKey = strArray[1]; // use previous authToken for the new authToken
- string str3 = YamlWebToken.Create(issueTo, timestamp, encodedSecretKey);
- return (issueTo + ":" + str3);
- }
- public class YamlWebToken
- {
- // Fields
- public static HmacAlgorithm DEFAULT_ALOGORITHM; // use Hmac algorith for generating token
- // Methods
- static YamlWebToken();
- public YamlWebToken();
- public static string Create(string issueTo, long timestamp, string encodedSecretKey);
- public static string Create(string issuedTo, long timestamp, string encodedSecretKey, HmacAlgorithm algorithm);
- // Nested Types
- public class HmacAlgorithm
- {
- // Methods
- public HmacAlgorithm(string name);
- public static HMAC CreateInstance(string name, byte[] key);
- // Properties
- public string Name { get; set; }
- }
- }
- public static string Create(string issueTo, long timestamp, string encodedSecretKey)
- {
- return Create(issueTo, timestamp, encodedSecretKey, DEFAULT_ALOGORITHM);
- }
- public static string Create(string issuedTo, long timestamp, string encodedSecretKey, HmacAlgorithm algorithm)
- {
- string str = "";
- try
- {
// core algorithm to make new session key - string str2 = string.Format("iat: {1}\n", issuedTo, timestamp);
- string str3 = Convert.ToBase64String(Encoding.get_UTF8().GetBytes(str2));
- string str4 = string.Empty;
- string str5 = str3 + "." + str4;
- byte[] key = Convert.FromBase64String(encodedSecretKey);
- string str6 = Convert.ToBase64String(HmacAlgorithm.CreateInstance(algorithm.Name, key).ComputeHash(Encoding.get_UTF8().GetBytes(str5)));
- str = str5 + "." + str6; // base64(issuedTo) + '..' + Hmac(SecretKey)
- }
- catch (Exception)
- {
- }
- return str;
- }
Anyway, I wrote an C# code that make updated session key...
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConsoleApplication1
- {
- class Program
- {
- static void Main(string[] args)
- {
- String issuedTo = "1" ;
- DateTime l = DateTime .UtcNow;
- long timestamp = (long )((l - new DateTime(1970, 1, 1, 0, 0, 0, 1)).TotalMilliseconds);
- String authToken = "????" // your old session key
- string[] strArray = authToken.Split(new char[] { ':' });
- string issueTo = strArray[0];
- string encodedSecretKey = strArray[1];
- string str2 = string .Format("iat: {1}\n", issuedTo, timestamp);
- string str3 = Convert .ToBase64String(Encoding.UTF8.GetBytes(str2));
- string str4 = string .Empty;
- string str5 = str3 + "." + str4;
- byte[] key = Convert .FromBase64String(encodedSecretKey);
- string str6 = Convert.ToBase64String(LINE.Service.YamlWebToken .HmacAlgorithm.CreateInstance(LINE.Service.YamlWebToken.DEFAULT_ALOGORITHM.Name, key).ComputeHash(Encoding.UTF8.GetBytes(str5)));
- String str = str5 + "." + str6; // base64(issuedTo) + '..' + Hmac(SecretKey)
- }
- }
- }
댓글 없음:
댓글 쓰기