Hai% nama pengguna%!

Dalam diskusi tentang
berita Passport
, diskusi hangat muncul tentang keamanan pesawat terbaru dari penulis Telegram.
Mari kita lihat bagaimana mengenkripsi data pribadi Anda dan berbicara tentang End-To-End yang asli.
Singkatnya, cara kerja Passport.
- Secara lokal, menggunakan kata sandi, Anda mengenkripsi data pribadi Anda (nama, email, pemindaian paspor, dokumen lain).
- Data terenkripsi + meta-informasi diunggah ke cloud Telegram.
- Saat Anda perlu masuk ke layanan, klien mengunduh data dari cloud, mendekripsinya dengan kata sandi, mendekripsinya ke kunci publik dari layanan yang meminta informasi, dan mengirimkannya.
Kami akan mempertimbangkan bagian pertama, yang berkaitan dengan enkripsi dan penyimpanan data pribadi.
End to End, menurut pengembang, terletak pada fakta bahwa cloud Telegram seharusnya tidak dapat mendekripsi data pribadi Anda, tetapi hanya melihat "noise acak".
Mari kita melihat lebih dekat pada kode algoritma enkripsi untuk data pribadi dari klien desktop yang berada di
sini dan melihat apakah hasil kerjanya memenuhi kriteria End-To-End.
Semuanya dimulai dengan kata sandi. Di sinilah tempat itu berubah menjadi kunci enkripsi menengah.
bytes::vector CountPasswordHashForSecret(
bytes::const_span salt,
bytes::const_span password) {
return openssl::Sha512(bytes::concatenate(
salt,
password,
salt));
}
, SHA-512. . !
2018 . GPU
SHA-512 . 10 GPU
8- 94 ( , , ) 5 .
, GPU, Telegram .
.
, :
bytes::vector GenerateSecretBytes() {
auto result = bytes::vector(kSecretSize);
memset_rand(result.data(), result.size());
const auto full = ranges::accumulate(
result,
0ULL,
[](uint64 sum, gsl::byte value) { return sum + uchar(value); });
const auto mod = (full % 255ULL);
const auto add = 255ULL + 239 - mod;
auto first = (static_cast<uchar>(result[0]) + add) % 255ULL;
result[0] = static_cast<gsl::byte>(first);
return result;
}
, .
ยซยป,
HMAC AEAD , , , 239, :
bool CheckBytesMod255(bytes::const_span bytes) {
const auto full = ranges::accumulate(
bytes,
0ULL,
[](uint64 sum, gsl::byte value) { return sum + uchar(value); });
const auto mod = (full % 255ULL);
return (mod == 239);
}
-,
. , , HMAC, .
. , . , :
EncryptedData EncryptData(
bytes::const_span bytes,
bytes::const_span dataSecret) {
constexpr auto kFromPadding = kMinPadding + kAlignTo - 1;
constexpr auto kPaddingDelta = kMaxPadding - kFromPadding;
const auto randomPadding = kFromPadding
+ (rand_value<uint32>() % kPaddingDelta);
const auto padding = randomPadding
- ((bytes.size() + randomPadding) % kAlignTo);
Assert(padding >= kMinPadding && padding <= kMaxPadding);
auto unencrypted = bytes::vector(padding + bytes.size());
Assert(unencrypted.size() % kAlignTo == 0);
unencrypted[0] = static_cast<gsl::byte>(padding);
memset_rand(unencrypted.data() + 1, padding - 1);
bytes::copy(
gsl::make_span(unencrypted).subspan(padding),
bytes);
32 255 .
dataHash. , .
const auto dataHash = openssl::Sha256(unencrypted);
const auto bytesForEncryptionKey = bytes::concatenate(
dataSecret,
dataHash);
auto params = PrepareAesParams(bytesForEncryptionKey);
return {
{ dataSecret.begin(), dataSecret.end() },
{ dataHash.begin(), dataHash.end() },
Encrypt(unencrypted, std::move(params))
};
}
. SHA-512 , dataHash.

:
- ,
ยซ ยป, , , . , AES (2^256).
Telegram , HMAC.
:
- , (GPU)
- (AES-NI)
- .
- - SHA-512 (GPU)
- (AES-NI)
- SHA-256, , :
if (padding < kMinPadding
|| padding > kMaxPadding
|| padding > decrypted.size()) {
, , . . GPU, AES-NI. , , . , ?
, ,
Don't roll your own crypto , End-to-End, .
, , , .
End-to-End
E2E , . , .
, , , , . Signal, (WhatsApp, etc). , , , .
, . .
Telegram , . , , .
P.S. E2E, VirgilSecurity
, .