프로그래밍을 하다 보면 암호화가 필요한 경우가 자주 있습니다.

아래는 두 개의 대표적인 암호화 알고리즘인 AES와 RSA의 사용 예시입니다.

이 암호화 알고리즘들은 Node.js의 crypto 패키지에 기본적으로 내장되어 있습니다.

아래 예시에는 암호화에 사용되는 키들이 소스 코드 안에 포함되어 있지만, 실제로는 키는 따로 파일에 저장하고 gitignore하여 안전하게 관리하세요.

AES

AES는 대표적인 양방향 암호화 알고리즘입니다.

양방향 암호란 한 개의 키로 데이터의 암호화, 복호화가 모두 가능한 암호입니다.

암호화된 암호문을 사용자에게 전달하고 이후에 사용자로 부터 받은 암호문 검증하는 상황 또는 비밀 키를 공유한 두 프로그램끼리 통신하는 상황에서 자주 이용됩니다.

const crypto = require('crypto');

const key = 'MySecretKey';

const encryptAES = (plainText) => {
    const iv = crypto.randomBytes(16);

    const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
    let encrypted = cipher.update(plainText);
    encrypted = Buffer.concat([encrypted, cipher.final()]);

    return iv.toString('hex') + encrypted.toString('hex');
};

const decryptAES = (cipherText) => {
    const iv = Buffer.from(cipherText.substring(0, 32), 'hex');
    const encrypted = Buffer.from(cipherText.substring(32), 'hex');

    const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
    let decrypted = decipher.update(encrypted);
    decrypted = Buffer.concat([decrypted, decipher.final()]);

    return decrypted.toString();
};

const text = 'Hello World!';

const encrypted = encryptAES(text);
console.log(encrypted);

const decrypted = decryptAES(encrypted);
console.log(decrypted);

RSA

RSA는 대표적인 공개키 암호화 알고리즘입니다.

공개키 암호란 공개키-비밀키 쌍을 생성한 후 공개키는 모두에게 공개하고 비밀키는 자신만 갖고 있는 상황에서, 공개키로 암호화된 암호문을 자신만 비밀키로 복호화하거나, 비밀키로 암호화된 암호문을 공개해 암호문을 생성한 것이 자신임을 증명하는 데에 이용할 수 있습니다.

const crypto = require('crypto');

const privateKey =
    '-----BEGIN RSA PRIVATE KEY-----\n' +
    'MIICXAIBAAKBgQCKLlFxb5RP4PuC74yHlyBZuAPhW5Qm2j5eXPjxyjtoEH1JCyhw\n' +
    '78CRCfkX2Y+3vSNwThoN0w0WldgzF6cW19HHbc5hL79WUS0k/iNhfRBZyQJTddV9\n' +
    'aRTFDi70yFp+RjnO2+WYmF64vJwMWRfrqGZURrRnzkOPiGohaCgmb79GMwIDAQAB\n' +
    'AoGAWPJbxpM2evytqakdYqJrVpVXGhdjFGdjwkZCkRHGj8QdgYlHLPuHj1VGHI4V\n' +
    'Lwb26vG7X669PA6Urr7I9bFS/QQBGx8MkFCR1lIHPmFatIwWj7yg+vrztCqKHhhu\n' +
    '7lOH2B/dOrPKZz+GC42a/Ln1RvyiJFPxgbCkWwsFWYqRDsECQQDJgnxS1qZEeJxm\n' +
    'yusYFT5TNtXMx2XWT7HH8fxElzJzgb9YSJv5hNsNfeIum7UMH37tihIeJAgOGmcT\n' +
    'e1E/bJzxAkEAr4vlcc3hq3oaGWfGy/E6g2Gccau57T63BYkZwPyHRBlpUMbCCt+T\n' +
    'd+mCUS+askGb3oqJZu10jkORmos8IgvlYwJAZwtD2fSL1425pNL1Pz51vYXX9Lyu\n' +
    'ddYQ+kbjEowir3BU0adno0Pt5EtQIzdacJWWiY/GTgVs3RFhTlQMKxu2cQJAYVkM\n' +
    'AQMx7PzGMmZ5OKlqUGc18VdQwL6xkfFIhdvES0BoRbIi8xKu3aVxbgIfIFD/1fYv\n' +
    'YhO2OhpASVqDG0JLjwJBALZfQlk9cDFJ51QSXrLokaLRWyVbaWyOtSB06lK/C2Hi\n' +
    'cOIpMo/scoicRiN0lxtl5TtksELhLll4xrF4ZEgqVR8=\n' +
    '-----END RSA PRIVATE KEY-----';

const publicKey =
    '-----BEGIN PUBLIC KEY-----\n' +
    'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCKLlFxb5RP4PuC74yHlyBZuAPh\n' +
    'W5Qm2j5eXPjxyjtoEH1JCyhw78CRCfkX2Y+3vSNwThoN0w0WldgzF6cW19HHbc5h\n' +
    'L79WUS0k/iNhfRBZyQJTddV9aRTFDi70yFp+RjnO2+WYmF64vJwMWRfrqGZURrRn\n' +
    'zkOPiGohaCgmb79GMwIDAQAB\n' +
    '-----END PUBLIC KEY-----';

const encryptPublicKey = function(plainText) {
    const buffer = Buffer.from(plainText);
    const encrypted = crypto.publicEncrypt(publicKey, buffer);
    return encrypted.toString("hex");
};

const decryptPrivateKey = function(cipherText) {
    const buffer = Buffer.from(cipherText, "hex");
    const decrypted = crypto.privateDecrypt(privateKey, buffer);
    return decrypted.toString("utf8");
};

const text = 'Hello World!';

const encrypted = encryptPublicKey(text);
console.log(encrypted);

const decrypted = decryptPrivateKey(encrypted);
console.log(decrypted);

위에서 쓰인 공개키와 비밀키는 예시이므로, 절대 같은 키를 사용하지 마세요.