Nhờ đó, văn bản mã hóa bằng Vigenère khó bị phá hơn nhiều so với Caesar Cipher thuần túy. Dù ngày nay vẫn không đủ an toàn cho hệ thống hiện đại, Vigenère Cipher là bước đệm rất tốt để hiểu các kỹ thuật mã hóa phức tạp hơn.
Vigenère Cipher giải bài toán gì?
Bài toán:
- Cho một đoạn plaintext (chuỗi ký tự).
- Cho một keyword gồm chữ cái (ví dụ: KEY, SECRET…).
- Cần mã hóa plaintext bằng cách dùng từng ký tự của keyword để quyết định độ dịch cho từng ký tự trong plaintext.
Mỗi chữ cái trong keyword được ánh xạ thành một số dịch:
- A hoặc a → 0
- B hoặc b → 1
- C hoặc c → 2
- …
- Z hoặc z → 25
Khi mã hóa, ta lặp keyword cho đến khi đủ dài để “phủ” toàn bộ plaintext, nhưng chỉ áp dụng trên các ký tự là chữ cái (a–z, A–Z).
Ý tưởng chính của Vigenère Cipher
- Chuẩn hóa keyword: bỏ ký tự không phải chữ cái, chuyển về uppercase để dễ xử lý.
- Duyệt từng ký tự trong plaintext:
- Nếu là chữ cái → dùng ký tự tương ứng trong keyword để xác định shift.
- Nếu không phải chữ cái (số, dấu cách, dấu câu…) → giữ nguyên, không làm keyword “tiến thêm”.
- Mã hóa:
C = (P + K) mod 26
- Giải mã:
P = (C - K + 26) mod 26
Trong đó:
- P: vị trí chữ plaintext (0–25).
- K: vị trí chữ keyword (0–25).
- C: vị trí chữ ciphertext (0–25).
Demo: Mã hóa – giải mã với Vigenère Cipher
Demo dưới đây cho phép bạn:
- Nhập plaintext/ciphertext.
- Nhập keyword.
- Chọn mode: Mã hóa (Encrypt) hoặc Giải mã (Decrypt).
- Xem kết quả và log từng ký tự: plaintext, ký tự key, kết quả.
Demo: Vigenère Cipher
Kết quả
Log từng ký tự
Ví dụ minh họa
Plaintext: HELLO WORLD
Keyword: KEY
Keyword lặp trên chữ cái (bỏ qua dấu cách):
Plain: H E L L O W O R L D
Key: K E Y K E Y K E Y K
Shift: 10 4 24 10 4 24 10 4 24 10
Kết quả mã hóa (Encrypt) sẽ là một chuỗi ciphertext tương ứng, mỗi chữ được dịch theo shift của keyword.
Code chính của Vigenère Cipher
function normalizeKeyword(keyword) {
var onlyLetters = keyword.replace(/[^A-Za-z]/g, "").toUpperCase();
return onlyLetters;
}
function vigenere(str, keyword, mode) {
var result = "";
var log = [];
var key = normalizeKeyword(keyword);
if (!key.length) {
return { result: "", log: ["Keyword trống hoặc không có chữ cái hợp lệ."] };
}
var keyIndex = 0;
for (var i = 0; i < str.length; i++) {
var ch = str[i];
var code = str.charCodeAt(i);
if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) {
var isUpper = code >= 65 && code <= 90;
var base = isUpper ? 65 : 97;
var p = code - base;
var kChar = key[keyIndex % key.length];
var k = kChar.charCodeAt(0) - 65; // 0-25
var c;
if (mode === "encrypt") {
c = (p + k) % 26;
} else {
c = (p - k + 26) % 26;
}
var outChar = String.fromCharCode(c + base);
result += outChar;
var direction = mode === "encrypt" ? "+" : "-";
log.push(
ch +
" (pos " +
p +
") " +
direction +
" " +
kChar +
" (" +
k +
") → " +
outChar
);
keyIndex++;
} else {
result += ch;
log.push(ch + " (giữ nguyên, không áp keyword)");
}
}
return { result: result, log: log };
}
Vigenère Cipher mạnh đến đâu?
- Mạnh hơn Caesar Cipher rất nhiều vì:
- Không còn chỉ 25 khả năng shift.
- Pattern dịch thay đổi theo keyword.
- Tuy nhiên, với kỹ thuật phân tích tần suất nâng cao và các công cụ hiện đại, Vigenère vẫn không an toàn cho bảo mật thực tế.
Ngày nay, Vigenère chủ yếu dùng trong giảng dạy và minh họa khái niệm polyalphabetic cipher, thay vì dùng trong hệ thống thật.
Kết luận
Vigenère Cipher là bước tiến tự nhiên từ Caesar Cipher: thay vì một độ dịch cố định, ta dùng cả một keyword để điều khiển việc mã hóa. Điều này giúp phá vỡ các pattern đơn giản và làm cho ciphertext trông “ngẫu nhiên” hơn nhiều.
Khi đã hiểu Vigenère, bạn sẽ dễ tiếp cận các kỹ thuật mã hóa hiện đại hơn, nơi key có thể rất dài, phức tạp và kết hợp với nhiều phép biến đổi khác nhau (như AES).
Trong bài tiếp theo của series “Thuật toán mã hóa & bảo mật cơ bản”, chúng ta sẽ đến với Base64 Encoding – không phải là mã hóa bảo mật, nhưng lại cực kỳ phổ biến trong web, API và token.
Bình luận