Thuộc nhóm thuật toán mã đối xứng, AES là thuật toán mã hoá theo khối rất quan trọng và bảo mật tốt và tốc độ nhanh hơn nhiều lần so với thuật toán mã hoá bất đối xứng RSA, đặc biệt khi kết hợp với RSA nó tạo thành một cặp đôi gần như hoàn hảo để bảo mật với tốc độ cao cho bất kỳ hệ thống nào.

Cách thức mã hoá

Cách thức mã hoá và giải mã sẽ phức tạp một chút:

  1. A sẽ gửi khoá bí mật cho B qua một phương thức bí mật nào đó.
  2. B khi nhận được khoá bí mật sẽ mã hoá văn bản bằng khoá này.
  3. B gửi lại văn bản đã được mã hoá cho A qua bất kỳ phương tiện nào, dù ai có thấy cũng không thể nào giải mã được.
  4. A khi nhận được văn bản đã được đã mã sẽ dùng khoá bí mật để giải mã văn bản.
    Bạn có thể tìm hiểu thêm về AES tại đây.

Mã nguồn sử dụng AES

Từ sơ đồ cách thức mã hoá, chúng ta có thể tạo ra aes.js với mã nguồn sử dụng RSA như sau:

const crypto = require('crypto');

function encrypt(text, key, iv) {
    const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv);
    let encrypted = cipher.update(text, 'utf-8', 'hex');
    encrypted += cipher.final('hex');
    return encrypted;
}

function decrypt(encryptedText, key, iv) {
    const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv);
    let decrypted = decipher.update(encryptedText, 'hex', 'utf-8');
    decrypted += decipher.final('utf-8');
    return decrypted;
}

const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

const textToEncrypt = 'Techmaster';
const encryptedText = encrypt(textToEncrypt, key, iv);
const decryptedText = decrypt(encryptedText, key, iv);

console.log('Original Text:', textToEncrypt);
console.log('Encrypted Text:', encryptedText);
console.log('Decrypted Text:', decryptedText);

Ở đây chúng ta có:

  1. aes-256-cbc: Nghĩa là chúng ta đang sử dụng thuật toán aes với khoá bí mật có độ dài là 256 bit = 32 byte, cách mã hoá sử dụng ở đây là CBC (Cipher Block Chaining) nghĩa mã hoá khối sau sẽ phụ thuộc vào khối trước và khối đầu tiên sẽ được tạo bởi một init vector (IV).
  2. Dữ liệu được mã hoá và hiển thị ở dạng hex.
  3. Dữ liệu sẽ được chia thành các khối 16 byte để mã hoá nên chúng ta khởi tạo init vector có độ dài là 16.

Chạy chương trình

Thông qua lệnh node rsa.js kết quả chúng ta nhận được là:

Original Text: Techmaster
Encrypted Text: 3b4d289588b41bc2bf08a88d286d30fd
Decrypted Text: Techmaster

Nhìn chung sử dụng AES tương đối đơn giản, tuy nhiên có một vẫn đề chỗ trao đổi khoá bí mật, đó là dù có trao đổi qua đâu thì cũng có nguy cơ bị lộ, gửi qua mail cũng có nguy cơ bị đọc trộm, trao đổi qua gặp mặt trực tiếp cũng có nguy cơ bị theo dõi, vậy nên trong các ứng dụng thực tế ngày này người ta thường kết hợp giữa AES và RSA để trao đổi khoá bí mật trước khi trao đổi dữ liệu.

Kết hợp giữa AES và RSA

Sơ đồ kết hợp giữa AES và RSA sẽ như sau:

  1. A sẽ tạo ra một cặp khoá RSA bí mật và công khai và gửi cho B khoá RSA công khai, trong lúc đó B cũng có thể tạo một khoá AES.
  2. B khi nhận được khoá RSA công khai từ A sẽ sử dụng khoá công khai này để mã hoá khoá AES.
  3. B gửi lại khoá AES đã được mã hoá cho A qua bất kỳ phương thức nào.
  4. A sau khi nhận được khoá AES đã được mã hoá sẽ sử dụng khoá RSA bí mật để giải mã.
  5. A sau khi đã giải mã được khoá AES sẽ sử dụng khoá này để mã hoá dữ liệu và gửi cho B.
    Minh hoạ bằng mã nguồn sẽ như sau:
const crypto = require('crypto');
const { generateKeyPairSync, publicEncrypt, privateDecrypt } = require('crypto');

const aesKey = crypto.randomBytes(32);
console.log('aesKey', aesKey.toString('hex'));

const { publicKey, privateKey } = generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: { type: 'spki', format: 'pem' },
    privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});

const encryptedAESKey = publicEncrypt(publicKey, aesKey);
console.log('Khóa phiên AES đã mã hóa:', encryptedAESKey.toString('hex'));

const decryptedAESKey = privateDecrypt(privateKey, encryptedAESKey);

console.log('Khóa phiên AES sau khi giải mã:', decryptedAESKey.toString('hex')); 

Tổng kết

Như vậy chúng ta đã cùng nhau tạo tìm hiểu về thuật toán AES kết hợp với RSA với NodeJS.


Cám ơn bạn đã quan tâm đến bài viết|video này. Để nhận được thêm các kiến thức bổ ích bạn có thể:

  1. Đọc các bài viết của TechMaster trên facebook: https://www.facebook.com/techmastervn
  2. Xem các video của TechMaster qua Youtube: https://www.youtube.com/@TechMasterVietnam nếu bạn thấy video/bài viết hay bạn có thể theo dõi kênh của TechMaster để nhận được thông báo về các video mới nhất nhé.
  3. Chat với techmaster qua Discord: https://discord.gg/yQjRTFXb7a