เทคโนโลยีการเข้ารหัสเกิดขึ้นมาเพื่อปกป้องความลับในการสื่อสารของข้อมูล โดยไม่ให้บุคคลที่ไม่เกี่ยวข้องสามารถรู้ความลับและบิดเบือนข้อมูลได้ โดยเราจะมาทำความเข้าใจว่า Symmetric และ Asymmetric Encryption คืออะไร?

Symmetric Encryption คืออะไร?

Symmetric Encryption

Symmetric Encryption คือการเข้ารหัสแบบสมมาตร โดยการเข้ารหัสและถอดรหัสด้วยกุญแจเดียวกันที่เรียกว่า Secret Key

อัลกอริทึมที่ใช้ในการเข้ารหัสแบบสมมาตร

  • Advanced Encryption Standard (AES)
  • Data Encryption Standard (DES)

ตัวอย่างการเข้ารหัสและถอดรหัสด้วยอัลกอริทึม AES

const crypto = require('crypto');
const algorithm = 'aes-256-gcm';
const SECERT_KEY = crypto.randomBytes(32);

const encrypt = (data) => {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(algorithm, SECERT_KEY, iv);

    // Hint: Larger inputs (it's GCM, after all!) should use the stream API
    let enc = cipher.update(data, 'utf8', 'base64');
    enc += cipher.final('base64');
    return [enc, iv, cipher.getAuthTag()];
};

const decrypt = (enc, iv, authTag) => {
    const decipher = crypto.createDecipheriv(algorithm, SECERT_KEY, iv);
    decipher.setAuthTag(authTag);
    let str = decipher.update(enc, 'base64', 'utf8');
    str += decipher.final('utf8');
    return str;
};


const [encrypted, iv, authTag] = encrypt('hello, world');
const decrypted = decrypt(encrypted, iv, authTag);

console.log(encrypted);
console.log(decrypted); // 'hello, world'

Asymmetric Encryption คืออะไร?

Asymmetric Encryption

Asymmetric Encryption ตือการเข้ารหัสแบบอสมมาตร จะเข้ารหัสและถอดรหัสด้วยกุญแจที่ต่างกัน โดยกุญแจที่เข้ารหัสจะเรียกว่า Public Key และกุญแจที่ถอดรหัสจะเรียกว่า Private Key

อัลกอริทึมที่ใช้ในการเข้ารหัสแบบอสมมาตร

  • Rivest Shamir Adleman (RSA)
  • Digital signature algorithm (DSA)
  • Elliptic curve cryptography (ECC)

ตัวอย่างการเข้ารหัสด้วยอัลกอริทึม Rivest Shamir Adleman (RSA)

Key Generation

สร้าง public key และ private key โดยใช้ไลบรารี่ crypto ของ nodejs

const crypto = require('crypto')
const PassPhrase = 'my secret passphrase'

const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
        cipher: 'aes-256-cbc',
        passphrase: PassPhrase
    }
});

console.log(privateKey)
console.log(publicKey)

Encryption

การเข้ารหัสข้อมูลโดยใช้ public key เข้ารหัสด้วยฟังก์ชัน publicEncrypt

const data = "my secret data";

const encryptedData = crypto.publicEncrypt(
    {
        key: publicKey,
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
        oaepHash: "sha256",
    },
    // We convert the data string to a buffer using 'Buffer.from'
    Buffer.from(data)
);

console.log("encypted data: ", encryptedData.toString("base64"));

Decryption

การถอดรหัสโดยใช้ private key ถอดรหัสด้วยฟังก์ชัน privateDecrypt

const decryptedData = crypto.privateDecrypt(
    {
        key: privateKey,
        passphrase: PassPhrase,
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
        oaepHash: "sha256",
    },
    encryptedData
);

console.log("decrypted data: ", decryptedData.toString());

Signing And Verification

สามารถใช้การเข้ารหัสแบบอสมมาตรเพื่อลงลายเซ็นและตรวจสอบลายเซ็นได้ โดยใช้ฟังก์ชัน sign และ verify ของไลบรารี่ crypto ของ nodejs

Signing And Verification
const verifiableData = "this need to be verified";

const signature = crypto.sign("sha256", Buffer.from(verifiableData), {
    key: privateKey,
    passphrase: PassPhrase,
    padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
});

console.log(signature.toString("base64"));


const isVerified = crypto.verify(
    "sha256",
    Buffer.from(verifiableData),
    {
        key: publicKey,
        padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
    },
    signature
);

// isVerified should be 'true' if the signature is valid
console.log("signature verified: ", isVerified);