719 lines
28 KiB
HTML
719 lines
28 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Архитектура Безопасности и Шифрования — Чепухаграм</title>
|
||
<meta name="description" content="Подробный разбор сквозного шифрования (E2EE) мессенджера Чепухаграм. Узнайте об использовании протоколов X25519, AES-256-GCM, PBKDF2 и поблочной защите медиафайлов.">
|
||
<!-- Google Fonts -->
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;700&family=Inter:wght@300;400;500;600;700&family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
|
||
|
||
<style>
|
||
:root {
|
||
--bg-color: #0b071a;
|
||
--bg-card: #14102d;
|
||
--accent-color: #7c4dff;
|
||
--accent-light: #9e75ff;
|
||
--accent-glow: rgba(124, 77, 255, 0.3);
|
||
--text-primary: #ffffff;
|
||
--text-secondary: #94a3b8;
|
||
--glass-bg: rgba(255, 255, 255, 0.03);
|
||
--glass-border: rgba(255, 255, 255, 0.08);
|
||
--code-bg: #110c26;
|
||
}
|
||
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Inter', sans-serif;
|
||
background-color: var(--bg-color);
|
||
color: var(--text-primary);
|
||
overflow-x: hidden;
|
||
line-height: 1.75;
|
||
}
|
||
|
||
h1, h2, h3, h4, .logo {
|
||
font-family: 'Outfit', sans-serif;
|
||
}
|
||
|
||
/* Custom Scrollbar */
|
||
::-webkit-scrollbar {
|
||
width: 8px;
|
||
}
|
||
::-webkit-scrollbar-track {
|
||
background: var(--bg-color);
|
||
}
|
||
::-webkit-scrollbar-thumb {
|
||
background: var(--glass-border);
|
||
border-radius: 4px;
|
||
transition: background 0.3s;
|
||
}
|
||
::-webkit-scrollbar-thumb:hover {
|
||
background: var(--accent-color);
|
||
}
|
||
|
||
.container {
|
||
width: 100%;
|
||
max-width: 1000px;
|
||
margin: 0 auto;
|
||
padding: 0 24px;
|
||
}
|
||
|
||
/* Header Navigation */
|
||
header {
|
||
background: rgba(11, 7, 26, 0.8);
|
||
backdrop-filter: blur(16px);
|
||
border-bottom: 1px solid var(--glass-border);
|
||
padding: 16px 0;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
}
|
||
|
||
.header-content {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.logo {
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
color: var(--text-primary);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.logo-dot {
|
||
width: 8px;
|
||
height: 8px;
|
||
background-color: var(--accent-color);
|
||
border-radius: 50%;
|
||
box-shadow: 0 0 10px var(--accent-color);
|
||
}
|
||
|
||
.btn-back {
|
||
color: var(--text-secondary);
|
||
text-decoration: none;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
transition: color 0.3s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
background: var(--glass-bg);
|
||
border: 1px solid var(--glass-border);
|
||
padding: 8px 16px;
|
||
border-radius: 20px;
|
||
}
|
||
|
||
.btn-back:hover {
|
||
color: var(--text-primary);
|
||
border-color: rgba(255, 255, 255, 0.2);
|
||
background: rgba(255, 255, 255, 0.06);
|
||
}
|
||
|
||
/* Hero Section */
|
||
.hero {
|
||
padding: 80px 0 40px 0;
|
||
background: radial-gradient(circle at 50% -20%, rgba(124, 77, 255, 0.12) 0%, transparent 60%);
|
||
}
|
||
|
||
.hero h1 {
|
||
font-size: 46px;
|
||
font-weight: 700;
|
||
margin-bottom: 16px;
|
||
line-height: 1.2;
|
||
background: linear-gradient(135deg, #ffffff 40%, #d1c4e9 100%);
|
||
-webkit-text-fill-color: transparent;
|
||
}
|
||
|
||
.hero-meta {
|
||
font-size: 14px;
|
||
color: var(--text-secondary);
|
||
margin-bottom: 40px;
|
||
}
|
||
|
||
/* Article Content */
|
||
.content-section {
|
||
padding-bottom: 80px;
|
||
}
|
||
|
||
.intro-text {
|
||
font-size: 18px;
|
||
font-weight: 300;
|
||
color: #e2e8f0;
|
||
margin-bottom: 40px;
|
||
line-height: 1.8;
|
||
}
|
||
|
||
h2 {
|
||
font-size: 28px;
|
||
font-weight: 700;
|
||
margin: 54px 0 24px 0;
|
||
border-left: 4px solid var(--accent-color);
|
||
padding-left: 16px;
|
||
color: #f8fafc;
|
||
}
|
||
|
||
h3 {
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
margin: 32px 0 16px 0;
|
||
color: #f1f5f9;
|
||
}
|
||
|
||
p {
|
||
margin-bottom: 24px;
|
||
color: #cbd5e1;
|
||
}
|
||
|
||
ul, ol {
|
||
margin-bottom: 28px;
|
||
padding-left: 24px;
|
||
color: #cbd5e1;
|
||
}
|
||
|
||
li {
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
/* Tech Spec Grid */
|
||
.spec-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||
gap: 20px;
|
||
margin: 40px 0;
|
||
}
|
||
|
||
.spec-card {
|
||
background: var(--bg-card);
|
||
border: 1px solid var(--glass-border);
|
||
border-radius: 16px;
|
||
padding: 28px 24px;
|
||
text-align: center;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
|
||
transition: transform 0.3s;
|
||
}
|
||
|
||
.spec-card:hover {
|
||
transform: translateY(-4px);
|
||
}
|
||
|
||
.spec-card .icon {
|
||
font-size: 32px;
|
||
margin-bottom: 16px;
|
||
display: inline-block;
|
||
}
|
||
|
||
.spec-card h3 {
|
||
font-size: 16px;
|
||
color: var(--text-primary);
|
||
margin: 0 0 8px 0;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.spec-card p {
|
||
font-size: 13px;
|
||
color: var(--text-secondary);
|
||
margin-bottom: 0;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
/* Cryptographic Exchange Diagram (CSS representation) */
|
||
.dh-diagram {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
background: var(--bg-card);
|
||
border: 1px solid var(--glass-border);
|
||
border-radius: 24px;
|
||
padding: 36px 30px;
|
||
margin: 40px 0;
|
||
gap: 20px;
|
||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
|
||
}
|
||
|
||
.dh-entity {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 12px;
|
||
width: 32%;
|
||
}
|
||
|
||
.dh-avatar {
|
||
width: 54px;
|
||
height: 54px;
|
||
background: linear-gradient(135deg, var(--accent-color), #b388ff);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-weight: 700;
|
||
color: white;
|
||
font-size: 15px;
|
||
box-shadow: 0 4px 15px var(--accent-glow);
|
||
}
|
||
|
||
.dh-avatar.bob {
|
||
background: linear-gradient(135deg, #00b0ff, #00e5ff);
|
||
box-shadow: 0 4px 15px rgba(0, 176, 255, 0.3);
|
||
}
|
||
|
||
.dh-key {
|
||
padding: 8px 12px;
|
||
border-radius: 8px;
|
||
font-size: 11px;
|
||
text-align: center;
|
||
width: 100%;
|
||
font-weight: 500;
|
||
font-family: 'Fira Code', monospace;
|
||
}
|
||
|
||
.dh-key.private {
|
||
background: rgba(239, 83, 80, 0.12);
|
||
border: 1px solid rgba(239, 83, 80, 0.25);
|
||
color: #ef5350;
|
||
}
|
||
|
||
.dh-key.public {
|
||
background: rgba(76, 217, 100, 0.12);
|
||
border: 1px solid rgba(76, 217, 100, 0.25);
|
||
color: #4cd964;
|
||
}
|
||
|
||
.dh-key.shared {
|
||
background: rgba(124, 77, 255, 0.15);
|
||
border: 1px solid rgba(124, 77, 255, 0.3);
|
||
color: #b388ff;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.dh-channel {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 12px;
|
||
font-size: 11px;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.dh-arrow {
|
||
background: rgba(255, 255, 255, 0.04);
|
||
padding: 6px 12px;
|
||
border-radius: 20px;
|
||
border: 1px solid var(--glass-border);
|
||
width: 100%;
|
||
text-align: center;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* File Block Stream Encryption Diagram */
|
||
.block-stream-diagram {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
background: var(--bg-card);
|
||
border: 1px solid var(--glass-border);
|
||
border-radius: 24px;
|
||
padding: 36px 30px;
|
||
margin: 40px 0;
|
||
gap: 20px;
|
||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
|
||
}
|
||
|
||
.stream-file {
|
||
background: linear-gradient(135deg, var(--accent-color) 0%, #5e35b1 100%);
|
||
padding: 12px 36px;
|
||
border-radius: 12px;
|
||
font-weight: 600;
|
||
box-shadow: 0 4px 15px var(--accent-glow);
|
||
font-size: 14px;
|
||
}
|
||
|
||
.stream-split {
|
||
font-size: 12px;
|
||
color: var(--text-secondary);
|
||
font-style: italic;
|
||
}
|
||
|
||
.stream-blocks {
|
||
display: flex;
|
||
gap: 16px;
|
||
width: 100%;
|
||
justify-content: center;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.stream-block {
|
||
background: rgba(255, 255, 255, 0.02);
|
||
border: 1px solid var(--glass-border);
|
||
border-radius: 14px;
|
||
padding: 18px;
|
||
flex: 1;
|
||
min-width: 220px;
|
||
text-align: center;
|
||
}
|
||
|
||
.stream-block.tail {
|
||
border-style: dashed;
|
||
border-color: rgba(255, 255, 255, 0.2);
|
||
}
|
||
|
||
.block-title {
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
display: block;
|
||
margin-bottom: 8px;
|
||
color: #fff;
|
||
}
|
||
|
||
.block-crypto {
|
||
font-size: 11px;
|
||
color: var(--accent-light);
|
||
margin-bottom: 10px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.block-result {
|
||
font-size: 11px;
|
||
color: var(--text-secondary);
|
||
background: rgba(0, 0, 0, 0.25);
|
||
padding: 8px 10px;
|
||
border-radius: 8px;
|
||
line-height: 1.4;
|
||
font-family: 'Fira Code', monospace;
|
||
}
|
||
|
||
/* Encryption Steps Visualizer */
|
||
.steps {
|
||
background: var(--glass-bg);
|
||
border: 1px solid var(--glass-border);
|
||
border-radius: 24px;
|
||
padding: 40px;
|
||
margin: 40px 0;
|
||
position: relative;
|
||
}
|
||
|
||
.step-item {
|
||
display: flex;
|
||
gap: 24px;
|
||
margin-bottom: 32px;
|
||
position: relative;
|
||
}
|
||
|
||
.step-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.step-item:not(:last-child)::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 36px;
|
||
left: 18px;
|
||
width: 2px;
|
||
height: calc(100% - 4px);
|
||
background: var(--glass-border);
|
||
}
|
||
|
||
.step-num {
|
||
width: 38px;
|
||
height: 38px;
|
||
background: var(--accent-color);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-weight: bold;
|
||
font-size: 15px;
|
||
flex-shrink: 0;
|
||
box-shadow: 0 0 10px var(--accent-glow);
|
||
}
|
||
|
||
.step-content h3 {
|
||
font-size: 18px;
|
||
margin: 0 0 8px 0;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.step-content p {
|
||
font-size: 14px;
|
||
color: var(--text-secondary);
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
/* Code Block Container */
|
||
.code-container {
|
||
background: var(--code-bg);
|
||
border: 1px solid var(--glass-border);
|
||
border-radius: 16px;
|
||
padding: 24px;
|
||
margin: 32px 0;
|
||
overflow-x: auto;
|
||
position: relative;
|
||
}
|
||
|
||
.code-container::before {
|
||
content: 'Dart / PointyCastle / Cryptography';
|
||
position: absolute;
|
||
top: 8px;
|
||
right: 16px;
|
||
font-size: 10px;
|
||
color: var(--text-secondary);
|
||
text-transform: uppercase;
|
||
letter-spacing: 1px;
|
||
}
|
||
|
||
code {
|
||
font-family: 'Fira Code', monospace;
|
||
font-size: 13px;
|
||
color: #e2e8f0;
|
||
}
|
||
|
||
/* Callout Box */
|
||
.callout {
|
||
background: rgba(124, 77, 255, 0.08);
|
||
border-left: 4px solid var(--accent-color);
|
||
padding: 20px 24px;
|
||
border-radius: 0 16px 16px 0;
|
||
margin: 32px 0;
|
||
}
|
||
|
||
.callout p {
|
||
margin-bottom: 0;
|
||
font-size: 14px;
|
||
color: #e2e8f0;
|
||
}
|
||
|
||
/* Footer */
|
||
footer {
|
||
border-top: 1px solid var(--glass-border);
|
||
padding: 45px 0;
|
||
text-align: center;
|
||
background: #06040e;
|
||
}
|
||
|
||
.footer-logo {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: white;
|
||
text-decoration: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.dh-diagram {
|
||
flex-direction: column;
|
||
gap: 30px;
|
||
padding: 30px 20px;
|
||
}
|
||
.dh-entity {
|
||
width: 100%;
|
||
}
|
||
.dh-channel {
|
||
width: 100%;
|
||
}
|
||
.block-stream-diagram {
|
||
padding: 30px 20px;
|
||
}
|
||
.stream-blocks {
|
||
flex-direction: column;
|
||
}
|
||
.hero h1 {
|
||
font-size: 34px;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- Header Navigation -->
|
||
<header>
|
||
<div class="container header-content">
|
||
<a href="../index.html" class="logo" id="headerLogo">
|
||
<span class="logo-dot"></span>Чепухаграм
|
||
</a>
|
||
<a href="../index.html" class="btn-back" id="backLink">
|
||
← На главную
|
||
</a>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Hero Header -->
|
||
<section class="hero">
|
||
<div class="container">
|
||
<h1 id="titleHeader">Безопасность и сквозное шифрование (E2EE)</h1>
|
||
<div class="hero-meta" id="metaDate">Обновлено: Июнь 2026 • Документация Чепухаграм</div>
|
||
<p class="intro-text" id="introDesc">В мессенджере Чепухаграм конфиденциальность переписки обеспечивается математическими законами. Никакие третьи лица, включая разработчиков и администраторов серверов, не могут получить доступ к содержимому ваших чатов.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Main Content -->
|
||
<div class="container content-section">
|
||
|
||
<!-- Technical Specifications -->
|
||
<div class="spec-grid" id="specGrid">
|
||
<div class="spec-card">
|
||
<span class="icon">🔑</span>
|
||
<h3>X25519</h3>
|
||
<p>Протокол Диффи-Хеллмана для генерации общего ключа (ECDH)</p>
|
||
</div>
|
||
<div class="spec-card">
|
||
<span class="icon">⚙️</span>
|
||
<h3>AES-256-GCM</h3>
|
||
<p>Симметричное шифрование с проверкой целостности данных</p>
|
||
</div>
|
||
<div class="spec-card">
|
||
<span class="icon">🔒</span>
|
||
<h3>PBKDF2</h3>
|
||
<p>Криптографическая деривация ключей на базе мастер-пароля (600,000 ит.)</p>
|
||
</div>
|
||
</div>
|
||
|
||
<h2 id="e2eeHeader">Принцип сквозного шифрования (E2EE)</h2>
|
||
<p>Шифрование «end-to-end» означает, что шифрование информации происходит непосредственно на устройстве отправителя, а дешифрование — только на устройстве получателя. Серверная часть выполняет лишь функцию почтальона — пересылает зашифрованные пакеты байт, не имея ключей для их расшифровки.</p>
|
||
|
||
<!-- ECDH Exchange Visual Diagram -->
|
||
<h3>Схема согласования ключей (X25519)</h3>
|
||
<div class="dh-diagram">
|
||
<div class="dh-entity">
|
||
<div class="dh-avatar">Вы</div>
|
||
<div class="dh-key private">Приватный ключ A</div>
|
||
<div class="dh-key public">Публичный ключ A</div>
|
||
<div class="dh-key shared">Общий секрет (K)</div>
|
||
</div>
|
||
<div class="dh-channel">
|
||
<div class="dh-arrow">публичный ключ A →</div>
|
||
<div class="dh-arrow">← публичный ключ B</div>
|
||
<p style="margin: 8px 0 0 0; text-align: center; font-size: 11px;">(сервер пересылает только публичные ключи)</p>
|
||
</div>
|
||
<div class="dh-entity">
|
||
<div class="dh-avatar bob">Собеседник</div>
|
||
<div class="dh-key private">Приватный ключ B</div>
|
||
<div class="dh-key public">Публичный ключ B</div>
|
||
<div class="dh-key shared">Общий секрет (K)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="steps" id="stepsSection">
|
||
<div class="step-item">
|
||
<div class="step-num">1</div>
|
||
<div class="step-content">
|
||
<h3>Создание пары ключей</h3>
|
||
<p>При первом запуске приложения Чепухаграм генерирует на устройстве пару асимметричных ключей X25519 (приватный и публичный). Публичный ключ отправляется на сервер для того, чтобы другие пользователи могли начать с вами чат.</p>
|
||
</div>
|
||
</div>
|
||
<div class="step-item">
|
||
<div class="step-num">2</div>
|
||
<div class="step-content">
|
||
<h3>Деривация общего секрета (Shared Secret)</h3>
|
||
<p>Когда вы открываете чат, приложение берет ваш приватный ключ X25519 и публичный ключ собеседника, вычисляя общий секрет по алгоритму ECDH. Этот секретный ключ никогда не передается по сети — обе стороны вычисляют его независимо на своих девайсах.</p>
|
||
</div>
|
||
</div>
|
||
<div class="step-item">
|
||
<div class="step-num">3</div>
|
||
<div class="step-content">
|
||
<h3>Симметричное шифрование</h3>
|
||
<p>Все отправляемые текстовые сообщения шифруются по стандарту AES-256-GCM с уникальным вектором инициализации (Nonce). Полученный шифротекст передается на сервер.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<h2 id="messagesCryptoHeader">Шифрование текстовых сообщений</h2>
|
||
<p>Каждое текстовое сообщение кодируется в массив байтов, после чего для него генерируется случайный 12-байтовый вектор инициализации (nonce). Данные шифруются на ключе sharedSecret по алгоритму AES-256-GCM. Результат представляет собой склеенный массив байтов: <code>nonce (12 байт) + mac (16 байт) + ciphertext (зашифрованный текст)</code>, закодированный в Base64.</p>
|
||
|
||
<div class="code-container" id="messageCode">
|
||
<pre><code>// Схематичный пример дешифровки сообщения на клиенте
|
||
Future<String> decryptMessage(String base64Data, SecretKey sharedKey) async {
|
||
final data = base64Decode(base64Data);
|
||
|
||
final nonce = data.sublist(0, 12);
|
||
final mac = data.sublist(12, 28);
|
||
final cipherText = data.sublist(28);
|
||
|
||
final decrypted = await aesGcm.decrypt(
|
||
SecretBox(cipherText, nonce: nonce, mac: Mac(mac)),
|
||
secretKey: sharedKey,
|
||
);
|
||
|
||
return utf8.decode(decrypted);
|
||
}</code></pre>
|
||
</div>
|
||
|
||
<h2 id="filesCryptoHeader">Поблочное шифрование медиафайлов</h2>
|
||
<p>Для предотвращения утечек данных при отправке медиафайлов (картинок, видео, голосовых заметок и документов), в Чепухаграм внедрена продвинутая поблочная система шифрования:</p>
|
||
<ol>
|
||
<li>При выборе файла генерируется случайный симметричный ключ файла (<code>fileKey</code>).</li>
|
||
<li>Ключ <code>fileKey</code> шифруется на общем ключе чата (<code>sharedSecret</code>) и отправляется на сервер как поле <code>encrypted_key</code>.</li>
|
||
<li>Сам файл считывается потоком и шифруется блоками по 64 КБ с использованием <code>fileKey</code>. К каждому зашифрованному блоку добавляется 4-байтовый заголовок, содержащий точную длину блока, и уникальный вектор инициализации с тегом аутентификации MAC.</li>
|
||
</ol>
|
||
|
||
<!-- Media block stream diagram -->
|
||
<h3>Архитектура поблочного крипто-стрима</h3>
|
||
<div class="block-stream-diagram">
|
||
<div class="stream-file">Исходный файл медиа</div>
|
||
<div class="stream-split">👇 Считывание блоками по 64 КБ</div>
|
||
<div class="stream-blocks">
|
||
<div class="stream-block">
|
||
<span class="block-title">Блок 1 (64 КБ)</span>
|
||
<div class="block-crypto">🔒 AES-256-GCM (fileKey)</div>
|
||
<div class="block-result">Длина (4б) + Nonce (12б) + Данные + MAC (16б)</div>
|
||
</div>
|
||
<div class="stream-block">
|
||
<span class="block-title">Блок 2 (64 КБ)</span>
|
||
<div class="block-crypto">🔒 AES-256-GCM (fileKey)</div>
|
||
<div class="block-result">Длина (4б) + Nonce (12б) + Данные + MAC (16б)</div>
|
||
</div>
|
||
<div class="stream-block tail">
|
||
<span class="block-title">Остаток (<64 КБ)</span>
|
||
<div class="block-crypto">🔒 AES-256-GCM (fileKey)</div>
|
||
<div class="block-result">Длина (4б) + Nonce (12б) + Данные + MAC (16б)</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="callout" id="fileSecurityNote">
|
||
<p><strong>Важно:</strong> Такой подход позволяет осуществлять потоковую дешифрацию медиа во время загрузки (стриминг), благодаря чему видео и аудиозаписи начинают воспроизводиться еще до полной загрузки файла.</p>
|
||
</div>
|
||
|
||
<h2 id="masterPassHeader">Резервная копия ключей и мастер-пароль</h2>
|
||
<p>Поскольку приватный ключ X25519 хранится в изолированном защищенном хранилище (Secure Storage) вашего смартфона, при переустановке приложения вы можете потерять доступ к переписке. Для предотвращения этого в Чепухаграм создана система защищенных резервных копий:</p>
|
||
<ul>
|
||
<li>Вы придумываете сложный <strong>Мастер-пароль</strong>.</li>
|
||
<li>На основе этого пароля с помощью алгоритма <strong>PBKDF2 (600 000 итераций, HMAC-SHA256, соль "chepuhagram_salt")</strong> генерируется ключ шифрования резервной копии.</li>
|
||
<li>Приватный ключ X25519 шифруется на этом ключе и отправляется на сервер как <code>encrypted_private_key</code>.</li>
|
||
<li>При входе на новом устройстве вы вводите мастер-пароль, приложение скачивает копию ключа, расшифровывает её на вашем устройстве, и вы снова можете читать все ваши чаты. Сервер видит только зашифрованный массив байт и не может его декодировать.</li>
|
||
</ul>
|
||
|
||
<h2 id="sessionSecurityHeader">Безопасность сессий и автозавершение</h2>
|
||
<p>Чепухаграм поддерживает одновременный вход на нескольких устройствах. Вся сессионная активность полностью подконтрольна пользователю:</p>
|
||
<p>При любом изменении пароля сквозного шифрования (или при полном сбросе ключей) все остальные активные сессии на сторонних девайсах автоматически инвалидируются на сервере и прекращают работу. Это защищает ваши чаты от несанкционированного доступа с ранее авторизованных устройств.</p>
|
||
</div>
|
||
|
||
<!-- Footer -->
|
||
<footer>
|
||
<div class="container">
|
||
<a href="../index.html" class="footer-logo">
|
||
<span class="logo-dot"></span>Чепухаграм
|
||
</a>
|
||
<p class="footer-text">Документ подготовлен техническим отделом Чепухаграм. Все криптографические операции соответствуют современным стандартам безопасности.</p>
|
||
</div>
|
||
</footer>
|
||
|
||
</body>
|
||
</html>
|