Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.45 KB | None | 0 0
  1. import { DataCenter } from './app';
  2.  
  3. function log(message) {
  4. console.log(`[MT Proto]`, message);
  5. }
  6.  
  7. interface AuthProcesor {
  8. next(decryptedData, authData?): AuthProcesor;
  9. }
  10.  
  11. function getFromStorage(id: string) {
  12. return localStorage.getItem(id);
  13. }
  14.  
  15. function setToStorage(id: string, data) {
  16. return localStorage.setItem(id, data);
  17. }
  18.  
  19. function getAuthKeyIdData(dc_id) {
  20. return JSON.parse((getFromStorage(dc_id+'auth_key_data') || '{}'));
  21. }
  22.  
  23. function setAuthKeyData(dc_id, data) {
  24. console.log('set');
  25. console.log(data);
  26. setToStorage(dc_id+'auth_key_data', JSON.stringify(data));
  27. }
  28.  
  29. export class Authorization {
  30. authData = {
  31. ...getAuthKeyIdData(this.dataCenter.dcId),
  32. };
  33. authStep: any = new BeginAuthorization();
  34. isAuthorized;
  35.  
  36. constructor(private dataCenter: DataCenter) {
  37. if (this.authData.authKeyID) {
  38. this.isAuthorized = true;
  39. }
  40. }
  41.  
  42. start() {
  43. this.authStep = this.authStep.next(this.authData, this.dataCenter);
  44. }
  45.  
  46. updateSalt(newSalt) {
  47. this.authData.serverSalt = longToBytes(newSalt);
  48. localStorage.setItem(this.dataCenter.dcId + 'auth_key_data', JSON.stringify(this.authData));
  49. }
  50.  
  51. onMessage(decryptedData) {
  52. this.authStep = this.authStep.next(decryptedData, this.authData, this.dataCenter);
  53. if (!this.authStep) {
  54. this.isAuthorized = true
  55. }
  56. }
  57. }
  58.  
  59. class BeginAuthorization implements AuthProcesor {
  60. next(auth, dc: DataCenter) {
  61. log('Begin authorization');
  62. auth.nonce = randomBytes(16);
  63. dc.sendPlainMessage('req_pq', { nonce: auth.nonce });
  64. return new RequestDhParams()
  65. }
  66. }
  67.  
  68. class RequestDhParams {
  69. next(decryptedData, auth, dc: DataCenter) {
  70. log('Request dh params');
  71. const tlSerializator = new TLSerialization({ mtproto: true });
  72. const desearelizator = new Desearelizator(decryptedData, true);
  73. desearelizator.desearelization.fetchInt();
  74. desearelizator.desearelization.fetchLong();
  75. desearelizator.desearelization.fetchLong();
  76. let obj = desearelizator.deserealize();
  77. let pq = pqPrimeFactorization(obj.pq);
  78. auth.newNonce = randomBytes(32);
  79. auth.serverNonce = obj['server_nonce'];
  80. tlSerializator.storeObject({
  81. _: 'p_q_inner_data',
  82. pq: obj.pq,
  83. p: pq[0],
  84. q: pq[1],
  85. nonce: auth.nonce,
  86. server_nonce: auth.serverNonce,
  87. new_nonce: auth.newNonce,
  88. }, 'P_Q_inner_data');
  89. let dataWithHash = concat(sha1BytesSync(tlSerializator.getBytes()), tlSerializator.getBytes());
  90. let rsa = selectRsaKeyByFingerPrint(obj['server_public_key_fingerprints']);
  91. dc.sendPlainMessage('req_DH_params', {
  92. nonce: auth.nonce,
  93. server_nonce: auth.serverNonce,
  94. p: pq[0],
  95. q: pq[1],
  96. public_key_fingerprint: rsa.fingerprint,
  97. encrypted_data: rsaEncrypt(rsa, dataWithHash),
  98. });
  99.  
  100. return new SetClientDhParams();
  101. }
  102. }
  103.  
  104. class SetClientDhParams {
  105. next(decryptedData, auth, dc: DataCenter) {
  106. log('Set client dh params');
  107. const desearelizator = new Desearelizator(decryptedData, true);
  108. desearelizator.desearelization.fetchInt();
  109. desearelizator.desearelization.fetchLong();
  110. desearelizator.desearelization.fetchLong();
  111.  
  112. let obj = desearelizator.deserealize();
  113. auth.tmpAesKey = tmpAesKey(auth.serverNonce, auth.newNonce);
  114. auth.tmpAesIv = tmpAesIv(auth.serverNonce, auth.newNonce);
  115.  
  116. const answerWithHash = aesDecryptSync(obj['encrypted_answer'], auth.tmpAesKey, auth.tmpAesIv);
  117. const innerDesearelizator = new Desearelizator(new Uint8Array(answerWithHash), true);
  118. innerDesearelizator.desearelization.fetchLong();
  119. innerDesearelizator.desearelization.fetchLong();
  120. let deser = innerDesearelizator.deserealize();
  121. const gBytes = bytesFromHex(deser.g.toString(16));
  122. auth.gA = deser['g_a'];
  123. auth.dhPrime = deser['dh_prime'];
  124. auth.randomB = randomBytes(256);
  125. ;
  126. auth.serverTime = deser.server_time
  127. let modpow = bytesModPow(gBytes, auth.randomB, auth.dhPrime);
  128. let tsSer = new TLSerialization({ mtproto: true });
  129. let serialization = tsSer;
  130.  
  131. tsSer.writeInt(1715713620);
  132. tsSer.storeObject({
  133. _: 'client_DH_inner_data',
  134. nonce: new Uint8Array(auth.nonce),
  135. server_nonce: new Uint8Array(auth.serverNonce),
  136. retry_id: [0, 0],
  137. g_b: modpow,
  138. }, 'client_DH_inner_data');
  139. const dataWithHash = concat(sha1BytesSync(new Uint8Array(serialization.getBytes()).buffer), new Uint8Array(serialization.getBytes()));
  140. const encryptedData = aesEncryptSync(dataWithHash, auth.tmpAesKey, auth.tmpAesIv);
  141. dc.sendPlainMessage('set_client_DH_params', {
  142. nonce: auth.nonce,
  143. server_nonce: auth.serverNonce,
  144. encrypted_data: encryptedData,
  145. });
  146. auth.localTime = tsNow();
  147. dc.applyServerTime(auth.serverTime, auth.localTime)
  148. return new AuthFinished();
  149. }
  150. }
  151.  
  152. class AuthFinished {
  153. next(decryptedData, auth, dataCenter) {
  154. let desearelizator = new Desearelizator(decryptedData, true);
  155. desearelizator.desearelization.fetchInt();
  156. desearelizator.desearelization.fetchLong();
  157. desearelizator.desearelization.fetchLong();
  158. desearelizator.deserealize();
  159. let authKey = bytesModPow(auth.gA, auth.randomB, auth.dhPrime);
  160. const authKeyHash = sha1BytesSync(authKey),
  161. authKeyAux = authKeyHash.slice(0, 8),
  162. authKeyID = authKeyHash.slice(-8)
  163. if (desearelizator.constructorName == 'dh_gen_ok') {
  164. log('It`s okay');
  165. const serverSalt = bytesXor(auth.newNonce.slice(0, 8), auth.serverNonce.slice(0, 8))
  166. //
  167.  
  168. auth.authKeyID = authKeyID;
  169. auth.authKey = authKey;
  170. auth.serverSalt = serverSalt;
  171. setAuthKeyData(dataCenter.dcId, { authKeyID, authKey, serverSalt });
  172. } else {
  173. console.warn('[MT Proto] ' + desearelizator.constructorName);
  174. }
  175. return undefined;
  176. }
  177. }
  178.  
  179.  
  180. const publicKeysHex: PublicKey[] = [{
  181. modulus:
  182. 'c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f' +
  183. '8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e5802' +
  184. '30e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b' +
  185. '8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d86' +
  186. '6b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b' +
  187. '6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083' +
  188. 'a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde7' +
  189. '4a5bfc920f6abf59ba5c75506373e7130f9042da922179251f',
  190. exponent: '010001',
  191. },
  192. {
  193. modulus: `00aeec36c8ffc109cb099624685b97
  194. 815415657bd76d8c9c3e398103d7ad
  195. 16c9bba6f525ed0412d7ae2c2de2b4
  196. 4e77d72cbf4b7438709a4e646a05c4
  197. 3427c7f184debf72947519680e6515
  198. 00890c6832796dd11f772c25ff8f57
  199. 6755afe055b0a3752c696eb7d8da0d
  200. 8be1faf38c9bdd97ce0a77d3916230
  201. c4032167100edd0f9e7a3a9b602d04
  202. 367b689536af0d64b613ccba796293
  203. 9d3b57682beb6dae5b608130b2e52a
  204. ca78ba023cf6ce806b1dc49c72cf92
  205. 8a7199d22e3d7ac84e47bc9427d023
  206. 6945d10dbd15177bab413fbf0edfda
  207. 09f014c7a7da088dde9759702ca760
  208. af2b8e4e97cc055c617bd74c3d9700
  209. 8635b98dc4d621b4891da9fb047304
  210. 7927`.split('\n').map((it) => it.trim()).join(''),
  211. exponent: '010001',
  212. },
  213. {
  214. modulus: `00bdf2c77d81f6afd47bd30f29ac76
  215. e55adfe70e487e5e48297e5a9055c9
  216. c07d2b93b4ed3994d3eca5098bf18d
  217. 978d54f8b7c713eb10247607e69af9
  218. ef44f38e28f8b439f257a11572945c
  219. c0406fe3f37bb92b79112db69eedf2
  220. dc71584a661638ea5becb9e2358507
  221. 4b80d57d9f5710dd30d2da940e0ada
  222. 2f1b878397dc1a72b5ce2531b6f7dd
  223. 158e09c828d03450ca0ff8a174deac
  224. ebcaa22dde84ef66ad370f259d18af
  225. 806638012da0ca4a70baa83d9c158f
  226. 3552bc9158e69bf332a45809e1c369
  227. 05a5caa12348dd57941a482131be7b
  228. 2355a5f4635374f3bd3ddf5ff925bf
  229. 4809ee27c1e67d9120c5fe08a9de45
  230. 8b1b4a3c5d0a428437f2beca81f4e2
  231. d5ff`.split('\n').map((it) => it.trim()).join(''),
  232. exponent: '010001',
  233. },
  234. {
  235. modulus: `00b3f762b739be98f343eb1921cf01
  236. 48cfa27ff7af02b6471213fed9daa0
  237. 098976e667750324f1abcea4c31e43
  238. b7d11f1579133f2b3d9fe27474e462
  239. 058884e5e1b123be9cbbc6a443b292
  240. 5c08520e7325e6f1a6d50e117eb61e
  241. a49d2534c8bb4d2ae4153fabe832b9
  242. edf4c5755fdd8b19940b81d1d96cf4
  243. 33d19e6a22968a85dc80f0312f596b
  244. d2530c1cfb28b5fe019ac9bc25cd9c
  245. 2a5d8a0f3a1c0c79bcca524d315b5e
  246. 21b5c26b46babe3d75d06d1cd33329
  247. ec782a0f22891ed1db42a1d6c0dea4
  248. 31428bc4d7aabdcf3e0eb6fda4e23e
  249. b7733e7727e9a1915580796c55188d
  250. 2596d2665ad1182ba7abf15aaa5a8b
  251. 779ea996317a20ae044b820bff35b6
  252. e8a`.split('\n').map((it) => it.trim()).join(''),
  253. exponent: '010001',
  254. },
  255. {
  256. modulus: `00be6a71558ee577ff03023cfa17aa
  257. b4e6c86383cff8a7ad38edb9fafe6f
  258. 323f2d5106cbc8cafb83b869cffd1c
  259. cf121cd743d509e589e68765c96601
  260. e813dc5b9dfc4be415c7a6526132d0
  261. 035ca33d6d6075d4f535122a1cdfe0
  262. 17041f1088d1419f65c8e5490ee613
  263. e16dbf662698c0f54870f0475fa893
  264. fc41eb55b08ff1ac211bc045ded31b
  265. e27d12c96d8d3cfc6a7ae8aa50bf2e
  266. e0f30ed507cc2581e3dec56de94f5d
  267. c0a7abee0be990b893f2887bd2c631
  268. 0a1e0a9e3e38bd34fded2541508dc1
  269. 02a9c9b4c95effd9dd2dfe96c29be6
  270. 47d6c69d66ca500843cfaed6e44019
  271. 6f1dbe0e2e22163c61ca48c79116fa
  272. 77216726749a976a1c4b0944b5121e
  273. 8c01`.split('\n').map((it) => it.trim()).join(''),
  274. exponent: '010001',
  275. },
  276. ];
  277.  
  278. let prepared = false;
  279. const tmpAesKey = (serverNonce, newNonce) => {
  280. const arr1 = concat(newNonce, serverNonce)
  281. const arr2 = concat(serverNonce, newNonce)
  282. const key1 = sha1BytesSync(arr1)
  283. const key2 = sha1BytesSync(arr2).slice(0, 12)
  284. return concat(key1, key2);
  285. }
  286.  
  287. const tmpAesIv = (serverNonce, newNonce) => {
  288. const arr1 = concat(serverNonce, newNonce)
  289. const arr2 = concat(newNonce, newNonce)
  290. const arr3 = newNonce.slice(0, 4)
  291. const key1 = sha1BytesSync(arr1)
  292. const key2 = sha1BytesSync(arr2)
  293. return concat(key1.slice(12), concat(key2, arr3));
  294. }
  295.  
  296.  
  297. function prepareRsaKeys() {
  298. if (prepared) return
  299.  
  300. publicKeysHex.forEach((it) => mapPrepare(it));
  301.  
  302. prepared = true
  303. }
  304.  
  305. let publicKeysParsed = {};
  306.  
  307. function selectRsaKeyByFingerPrint(fingerprints: string[]) {
  308. let fingerprintHex, foundKey
  309. for (const fingerprint of fingerprints) {
  310. fingerprintHex = strDecToHex(fingerprint);
  311. console.log(fingerprintHex);
  312. foundKey = publicKeysParsed[fingerprintHex]
  313. if (foundKey)
  314. return { fingerprint, ...foundKey }
  315. }
  316. return false
  317. }
  318.  
  319.  
  320. const mapPrepare = ({ modulus, exponent }) => {
  321. const serializatorTL = new TLSerialization({ mptroto: true });
  322. serializatorTL.storeBytes(bytesFromHex(modulus));
  323. serializatorTL.storeBytes(bytesFromHex(exponent));
  324. let fingerprintBytes = sha1BytesSync(serializatorTL.getBytes()).slice(-8);
  325. fingerprintBytes = fingerprintBytes.reverse();
  326.  
  327. publicKeysParsed[bytesToHex(fingerprintBytes)] = {
  328. modulus,
  329. exponent,
  330. }
  331. console.log(publicKeysParsed);
  332. };
  333.  
  334. prepareRsaKeys();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement