feat: отправка chatCacheFingerprint и exp в login-пакете (opcode 19)
This commit is contained in:
+5
-1
@@ -133,4 +133,8 @@ agents.md
|
|||||||
|
|
||||||
# Environment variables
|
# Environment variables
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
|
# Локальные дампы трафика и скрипты анализа (содержат секреты)
|
||||||
|
komet.txt
|
||||||
|
original_app.txt
|
||||||
|
fingerprint.py
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ class Api {
|
|||||||
|
|
||||||
Map<dynamic, dynamic>? get userAgent => _userAgent;
|
Map<dynamic, dynamic>? get userAgent => _userAgent;
|
||||||
|
|
||||||
|
int? _callsSeed;
|
||||||
|
String? _deviceId;
|
||||||
|
|
||||||
|
int? get callsSeed => _callsSeed;
|
||||||
|
String? get deviceId => _deviceId;
|
||||||
|
|
||||||
List<CountryName>? _registrationCountries;
|
List<CountryName>? _registrationCountries;
|
||||||
|
|
||||||
List<CountryName> get registrationCountries =>
|
List<CountryName> get registrationCountries =>
|
||||||
@@ -111,6 +117,7 @@ class Api {
|
|||||||
try {
|
try {
|
||||||
final response = await sendHandshake();
|
final response = await sendHandshake();
|
||||||
if (response.isOk) {
|
if (response.isOk) {
|
||||||
|
_callsSeed = response.payload['callsSeed'] as int?;
|
||||||
_registrationCountries = _parseRegistrationCountries(response.payload);
|
_registrationCountries = _parseRegistrationCountries(response.payload);
|
||||||
_setSessionState(SessionState.online);
|
_setSessionState(SessionState.online);
|
||||||
_startPinging();
|
_startPinging();
|
||||||
@@ -242,6 +249,8 @@ class Api {
|
|||||||
'buildNumber': buildNumber,
|
'buildNumber': buildNumber,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_deviceId = deviceId;
|
||||||
|
|
||||||
final payload = <dynamic, dynamic>{
|
final payload = <dynamic, dynamic>{
|
||||||
'mt_instanceid': await DeviceIdentity.instanceId(),
|
'mt_instanceid': await DeviceIdentity.instanceId(),
|
||||||
'clientSessionId': DeviceIdentity.clientSessionId,
|
'clientSessionId': DeviceIdentity.clientSessionId,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
import '../api.dart';
|
import '../api.dart';
|
||||||
|
import '../../core/protocol/chat_cache_fingerprint.dart';
|
||||||
import '../../core/protocol/opcode_map.dart';
|
import '../../core/protocol/opcode_map.dart';
|
||||||
import '../../core/protocol/packet.dart';
|
import '../../core/protocol/packet.dart';
|
||||||
import '../../core/storage/app_database.dart';
|
import '../../core/storage/app_database.dart';
|
||||||
@@ -1048,9 +1050,18 @@ class AccountModule {
|
|||||||
final payload = <dynamic, dynamic>{
|
final payload = <dynamic, dynamic>{
|
||||||
'token': token,
|
'token': token,
|
||||||
'interactive': true,
|
'interactive': true,
|
||||||
if (_api.userAgent != null) 'userAgent': _api.userAgent,
|
'exp': {
|
||||||
|
'chatsCountGroups': Uint8List.fromList([0x0b, 0x32]),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
final callsSeed = _api.callsSeed;
|
||||||
|
final deviceId = _api.deviceId;
|
||||||
|
if (callsSeed != null && deviceId != null) {
|
||||||
|
payload['chatCacheFingerprint'] =
|
||||||
|
ChatCacheFingerprint.compute(callsSeed, deviceId);
|
||||||
|
}
|
||||||
|
|
||||||
if (sync != null) {
|
if (sync != null) {
|
||||||
payload['presenceSync'] = sync.presenceSync;
|
payload['presenceSync'] = sync.presenceSync;
|
||||||
payload['chatsSync'] = sync.chatsSync;
|
payload['chatsSync'] = sync.chatsSync;
|
||||||
@@ -1060,9 +1071,6 @@ class AccountModule {
|
|||||||
payload['bannersSync'] = sync.bannersSync;
|
payload['bannersSync'] = sync.bannersSync;
|
||||||
payload['lastLogin'] = sync.lastLogin;
|
payload['lastLogin'] = sync.lastLogin;
|
||||||
if (sync.configHash != null) payload['configHash'] = sync.configHash;
|
if (sync.configHash != null) payload['configHash'] = sync.configHash;
|
||||||
if (sync.chatCacheFingerprint != null) {
|
|
||||||
payload['chatCacheFingerprint'] = sync.chatCacheFingerprint;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
payload['presenceSync'] = 0;
|
payload['presenceSync'] = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:crypto/crypto.dart';
|
||||||
|
|
||||||
|
class ChatCacheFingerprint {
|
||||||
|
static final Uint8List _signatureDigest = _hex(
|
||||||
|
'1684414033eb263e2c615f8b7df5ed8793850a07656304997fbf07e9e21e1e93',
|
||||||
|
);
|
||||||
|
static final Uint8List _soDigest = _hex(
|
||||||
|
'c77b89270f44bd26c218a946c18911f2b156312693ea00b419d169b71c1ed111',
|
||||||
|
);
|
||||||
|
static final Uint8List _dexDigest = _hex(
|
||||||
|
'490a2746c7ebbff050353c575a186ca65bc708f9b6e0c1329b59a3bfab6c3924',
|
||||||
|
);
|
||||||
|
|
||||||
|
static Uint8List compute(int callsSeed, String deviceId) {
|
||||||
|
final seed = _int64BigEndian(callsSeed);
|
||||||
|
final device = Uint8List.fromList(utf8.encode(deviceId));
|
||||||
|
final result = BytesBuilder();
|
||||||
|
result.add(_sha256(_signatureDigest, seed, device));
|
||||||
|
result.add(_sha256(_soDigest, seed, device));
|
||||||
|
result.add(_sha256(_dexDigest, seed, device));
|
||||||
|
return result.toBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<int> _sha256(Uint8List a, Uint8List b, Uint8List c) {
|
||||||
|
final builder = BytesBuilder()
|
||||||
|
..add(a)
|
||||||
|
..add(b)
|
||||||
|
..add(c);
|
||||||
|
return sha256.convert(builder.toBytes()).bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint8List _int64BigEndian(int value) {
|
||||||
|
final data = ByteData(8)..setInt64(0, value, Endian.big);
|
||||||
|
return data.buffer.asUint8List();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Uint8List _hex(String hex) {
|
||||||
|
final out = Uint8List(hex.length ~/ 2);
|
||||||
|
for (var i = 0; i < out.length; i++) {
|
||||||
|
out[i] = int.parse(hex.substring(i * 2, i * 2 + 2), radix: 16);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -130,7 +130,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.5+2"
|
version: "0.3.5+2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ dependencies:
|
|||||||
dart_lz4: ^1.0.0
|
dart_lz4: ^1.0.0
|
||||||
libcompress: ^1.0.0
|
libcompress: ^1.0.0
|
||||||
msgpack_dart: ^1.0.1
|
msgpack_dart: ^1.0.1
|
||||||
|
crypto: ^3.0.7
|
||||||
logger: ^2.6.2
|
logger: ^2.6.2
|
||||||
device_info_plus: 12.3.0
|
device_info_plus: 12.3.0
|
||||||
flutter_timezone: ^5.0.1
|
flutter_timezone: ^5.0.1
|
||||||
|
|||||||
Reference in New Issue
Block a user