crypto - Node.js

crypto とは

Node.js の暗号化機能を提供するモジュール

暗号化とハッシュ化の違いは、暗号化は、元のデータを特定の鍵を用いて変換し、権限を持つ者のみがそのデータを復元できるようにする仕組みです。

これに対し、ハッシュ化は一度暗号化されたデータを元の状態に戻すことはできません。

シークレットキーの作成

crypto.scryptSync 関数は、パスワードベースのキー導出関数です。

パスワードベースのキー導出関数とは、元となるパスワードから安全な暗号キーを生成するための特殊なアルゴリズムを用いた関数です。

salt の値は、すくなくとも16バイトの長さにすることが推奨されています。

const crypto = require("crypto");

const secret = "secret";
const salt = "AkdioaA38GDAKkaeei";

const key = crypto.scryptSync(secret, salt, 32);
console.log(key.toString("hex"));

関数化

function generateKey(){
    const secret = "secret";
    const salt = "AkdioaA38GDAKkaeei"; 
    const key = crypto.scryptSync(secret, salt, 32);
    return key
}

ランダムなソルトを作成するには、以下のようにします。

const crypto = require('crypto');

// ランダムな16バイトのソルトを生成する
const salt = crypto.randomBytes(16).toString('hex');
console.log(salt);

暗号化と複合化

crypto がサポートする暗号化アルゴリズムを調べるには以下のようにします。

const crypto = require("crypto");
const cipers = crypto.getCiphers();

console.log(cipers);
const crypto = require("crypto");

function generateKey(){
    const secret = "secret";
    const salt = "AkdioaA38GDAKkaeei"; 
    const key = crypto.scryptSync(secret, salt, 32);
    return key
}

const password = "password";

const key = generateKey();

const iv = crypto.randomBytes(16);

const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encryptedPassword = cipher.update(password, 'utf-8', 'hex');
encryptedPassword += cipher.final('hex');

console.log(encryptedPassword);


const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
let decrypted = decipher.update(encryptedPassword, "hex", "utf8");
decrypted += decipher.final("utf8");

console.log(decrypted);

関数化

const crypto = require("crypto");

// シークレットキーの作成
function generateKey(){
    const secret = "secret";
    const salt = "AkdioaA38GDAKkaeei"; 
    const key = crypto.scryptSync(secret, salt, 32);
    return key
}

// 暗号化
function encrypt(password, key){
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
    let encryptedPassword = cipher.update(password, 'utf-8', 'hex');
    encryptedPassword += cipher.final('hex');
    return { iv, encryptedPassword }
}

// 複合化
function decrypt(password, iv, key){
    const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
    let decrypted = decipher.update(password, "hex", "utf8");
    decrypted += decipher.final("utf8");
    return decrypted;
}

const password = "password";
const key = generateKey();

const { iv, encryptedPassword } = encrypt(password, key)

console.log(encryptedPassword);
console.log(decrypt(encryptedPassword, iv, key));

cipher : サイファー

暗号

crypto.randomBytes 関数は、疑似ランダムデータを生成します。コールバック関数が指定されていない場合は同期的に生成され、バッファとして値が返されます。

const crypto = require("crypto");

const iv = crypto.randomBytes(16);
console.log(iv.toString("hex"));

ハッシュアルゴリズム

ハッシュアルゴリズムを調べるには以下のようにします。

const crypto = require("crypto");
const hashes = crypto.getHashes();
console.log(hashes);
const crypto = require("crypto");

const password ='password';

const ecdh = crypto.createECDH('secp256k1');
const salt = ecdh.generateKeys();
console.log(salt.toString("hex"));

const sha512 = crypto.createHash('sha512');
sha512.update(password + salt.toString("hex"));
const hash = sha512.digest('hex');

console.log(hash);

「 hash.update(data[, inputEncoding]) 」は、指定された data でハッシュの内容を更新します。

「 hash.digest([encoding]) 」は、ハッシュ化するために渡されたすべてのデータのダイジェストを計算します。 また、digest()メソッドが呼ばれた後は、ハッシュオブジェクトは使えません。