AES
Өнөөгийн хамгийн өргөн хэрэглэгддэг симметрик блок шифр.
Чухал анхааруулга
Нэг л key-ээр nonce-ийг хэзээ ч давтаж ашиглаж болохгүй (never reuse a nonce with the same key). Давтвал confidentiality бүрэн эвдэрч, хоёр ciphertext-ийг XOR хийж plaintext-ийн мэдээлэл гаргаж авах боломжтой болохоос гадна GHASH-ийн authentication key сэргээгдэж бүх ирээдүйн зурвасыг хуурамчаар баталгаажуулах эрсдэлтэй.
Юу вэ?
Advanced Encryption Standard (AES) нь 2001 онд NIST-ийн FIPS-197 стандартаар баталсан симметрик блок шифр. 128 битийн блокоор ажиллаж, 128/192/256 битийн түлхүүр ашигладаг.
Хэрхэн ажилладаг вэ?
SubBytes, ShiftRows, MixColumns, AddRoundKey гэсэн дөрвөн үйлдлийг хэд хэдэн "round" (түлхүүрийн уртаас хамааран 10, 12 эсвэл 14) дараалан давтдаг substitution-permutation network юм.
Хаана ашиглагддаг вэ?
- TLS/HTTPS холболт
- Диск/файл шифрлэлт (BitLocker, FileVault)
- Wi-Fi (WPA2/WPA3)
- VPN
Техникийн үзүүлэлт
- Түлхүүрийн урт
- 128 эсвэл 256 bit
- Nonce-ийн урт
- 96 bit (12 byte) — стандарт хэмжээ; санамсаргүй эсвэл тоолуур (counter) байж болно
- Баталгаажуулах tag-ийн урт
- 128 bit (16 byte) — баталгаажуулалтын тэмдэг (authentication tag)
Түгээмэл алдаа
- Нэг key-ээр nonce-ийг давтах — ялангуяа санамсаргүй 96-bit nonce-ийг нэг key дор хэт олон удаа (~2^32 орчим) үүсгэх нь давхцлын магадлалыг (birthday bound) эрсдэлтэй түвшинд хүргэдэг
- Authentication tag-ийг бүрэн шалгахаас өмнө тайлагдсан (decrypt хийсэн) өгөгдлийг ашиглах эсвэл хэрэглэгчид харуулах
- Ciphertext-ийн хамт nonce-ийг хадгалахгүй орхих — decrypt хийхэд яг тэр nonce давхар шаардлагатай
- Нэг key-ээр хэт их хэмжээний өгөгдөл шифрлэж, key rotation хийхгүй удаан ашиглах
Жишээ код
// Node.js — AES-256-GCM: nonce (IV) бүрийг ЗААВАЛ шинээр, санамсаргүй үүсгэнэ
import { randomBytes, createCipheriv, createDecipheriv } from "node:crypto";
const key = randomBytes(32); // 256-bit key
const nonce = randomBytes(12); // 96-bit nonce — key бүрд ДАХИН АШИГЛАХГҮЙ
const cipher = createCipheriv("aes-256-gcm", key, nonce);
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
const authTag = cipher.getAuthTag(); // 128-bit tag — nonce-тэй хамт дамжуулна
// Тайлахдаа яг тэр nonce, authTag-аа дамжуулж, tag шалгалт амжилтгүй бол
// decipher.final() throw хийнэ — гаралтыг ашиглахаас өмнө энэ алдааг барина.
const decipher = createDecipheriv("aes-256-gcm", key, nonce);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);