CRYPTOGRAPHY
Блок шифр

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()]);

Эх сурвалж

Стандарт: FIPS 197