рд╣рд╛рдп% рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо%!

рдкрд╛рд╕рдкреЛрд░реНрдЯ
рд╕рдорд╛рдЪрд╛рд░ рдХреА рдЪрд░реНрдЪрд╛ рдореЗрдВ
, рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдХреЗ рд▓реЗрдЦрдХреЛрдВ рд╕реЗ рдирд╡реАрдирддрдо рд╢рд┐рд▓реНрдк рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд░реНрдЪрд╛ рд╣реБрдИред
рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрдЯрд╛ рдХреЛ рдХреИрд╕реЗ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдПрдВрдб-рдЯреВ-рдПрдВрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддрд╛ рд╣реИред
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдкрд╛рд╕рдкреЛрд░реНрдЯ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
- рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ, рдкрд╛рд╕рд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЕрдкрдиреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрдЯрд╛ (рдирд╛рдо, рдИрдореЗрд▓, рдкрд╛рд╕рдкреЛрд░реНрдЯ рд╕реНрдХреИрди, рдЕрдиреНрдп рджрд╕реНрддрд╛рд╡реЗрдЬрд╝) рдХреЛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░рддреЗ рд╣реИрдВред
- рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдбреЗрдЯрд╛ + рдореЗрдЯрд╛-рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдХреНрд▓рд╛рдЙрдб рдкрд░ рдЕрдкрд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдЬрдм рдЖрдкрдХреЛ рд╕реЗрд╡рд╛ рдореЗрдВ рд▓реЙрдЧ рдЗрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреНрд▓рд╛рдЙрдб рд╕реЗ рдбреЗрдЯрд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдкрд╛рд╕рд╡рд░реНрдб рдХреЗ рд╕рд╛рде рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдЙрд╕ рд╕реЗрд╡рд╛ рдХреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреБрдВрдЬреА рдХреЛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреА рд╣реИ, рдФрд░ рдЗрд╕реЗ рднреЗрдЬрддреА рд╣реИред
рд╣рдо рдкрд╣рд▓реЗ рднрд╛рдЧ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрдЯрд╛ рдХреЗ рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдФрд░ рднрдВрдбрд╛рд░рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред
рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдПрдВрдб рдЯреВ рдПрдВрдб, рдЗрд╕ рддрдереНрдп рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ рдХрд┐ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдХреНрд▓рд╛рдЙрдб рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрдЯрд╛ рдХреЛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ "рд░реИрдВрдбрдо рд╢реЛрд░" рджреЗрдЦрддрд╛ рд╣реИред
рдЖрдЗрдП
рдпрд╣рд╛рдВ рд╕реНрдерд┐рдд рдбреЗрд╕реНрдХрдЯреЙрдк рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдХреЛрдб рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕рдХреЗ рдХрд╛рдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдВрдб-рдЯреВ-рдПрдВрдб рдорд╛рдирджрдВрдбреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рд╕рдм рдПрдХ рдкрд╛рд╕рд╡рд░реНрдб рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣рд╛рдВ рд╡рд╣ рд╕реНрдерд╛рди рд╣реИ рдЬрд╣рд╛рдВ рдпрд╣ рдПрдХ рдордзреНрдпрд╡рд░реНрддреА рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХреБрдВрдЬреА рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред
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
, .