Node.js crypto モジュール
Node.js のcryptoモジュールは組み込みモジュールであり、暗号化機能を提供します。OpenSSL のハッシュ、HMAC、暗号化、復号、署名、検証機能のラッパーを含みます。開発者は Node.js アプリケーションでさまざまな暗号化操作を実行できます。
コア機能
ハッシュアルゴリズム
ハッシュアルゴリズムは、任意の長さの入力を固定長の出力に変換する一方向関数です。cryptoモジュールは SHA-256、MD5 など複数のハッシュアルゴリズムをサポートしています。
例
const crypto = require('crypto');
// SHA-256 ハッシュを作成
const hash = crypto.createHash('sha256');
hash.update('Hello World');
console.log(hash.digest('hex'));
// 出力: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146
// SHA-256 ハッシュを作成
const hash = crypto.createHash('sha256');
hash.update('Hello World');
console.log(hash.digest('hex'));
// 出力: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146
HMAC(鍵付きハッシュメッセージ認証コード)
HMAC は、暗号化ハッシュ関数と鍵を組み合わせたメッセージ認証メカニズムです。
例
const crypto = require('crypto');
const secret = 'mysecret';
const hmac = crypto.createHmac('sha256', secret);
hmac.update('Hello World');
console.log(hmac.digest('hex'));
// 出力: 9b8e8b0e3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a
const secret = 'mysecret';
const hmac = crypto.createHmac('sha256', secret);
hmac.update('Hello World');
console.log(hmac.digest('hex'));
// 出力: 9b8e8b0e3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a3b9e9b1a
暗号化と復号
対称暗号化
対称暗号化は、暗号化と復号に同じ鍵を使用します。cryptoモジュールは AES、DES などのアルゴリズムをサポートしています。
例
const crypto = require('crypto');
// 暗号化
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('Hello World', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);
// 復号
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// 暗号化
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update('Hello World', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);
// 復号
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
非対称暗号化
非対称暗号化は公開鍵と秘密鍵のペアを使用し、公開鍵は暗号化に、秘密鍵は復号に使用されます。
例
const crypto = require('crypto');
// 鍵ペアを生成
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 暗号化
const encryptedData = crypto.publicEncrypt(
publicKey,
Buffer.from('Hello World')
);
console.log(encryptedData.toString('base64'));
// 復号
const decryptedData = crypto.privateDecrypt(
privateKey,
encryptedData
);
console.log(decryptedData.toString());
// 鍵ペアを生成
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 暗号化
const encryptedData = crypto.publicEncrypt(
publicKey,
Buffer.from('Hello World')
);
console.log(encryptedData.toString('base64'));
// 復号
const decryptedData = crypto.privateDecrypt(
privateKey,
encryptedData
);
console.log(decryptedData.toString());
デジタル署名と検証
デジタル署名は、データの完全性と送信元を検証するために使用されます。
例
const crypto = require('crypto');
// 鍵ペアを生成
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 署名を作成
const sign = crypto.createSign('SHA256');
sign.update('some data to sign');
const signature = sign.sign(privateKey, 'hex');
console.log(signature);
// 署名を検証
const verify = crypto.createVerify('SHA256');
verify.update('some data to sign');
console.log(verify.verify(publicKey, signature, 'hex'));
// 出力: true
// 鍵ペアを生成
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 署名を作成
const sign = crypto.createSign('SHA256');
sign.update('some data to sign');
const signature = sign.sign(privateKey, 'hex');
console.log(signature);
// 署名を検証
const verify = crypto.createVerify('SHA256');
verify.update('some data to sign');
console.log(verify.verify(publicKey, signature, 'hex'));
// 出力: true
乱数生成
cryptoモジュールは、暗号学的に安全な乱数を生成するメソッドを提供します。
例
const crypto = require('crypto');
// 16 バイトの乱数を生成
const randomBytes = crypto.randomBytes(16);
console.log(randomBytes.toString('hex'));
// ランダムな整数を生成
const randomInt = crypto.randomInt(1, 100);
console.log(randomInt);
// 16 バイトの乱数を生成
const randomBytes = crypto.randomBytes(16);
console.log(randomBytes.toString('hex'));
// ランダムな整数を生成
const randomInt = crypto.randomInt(1, 100);
console.log(randomInt);
セキュリティ上の注意事項
- 鍵管理:鍵をコードにハードコードせず、環境変数または鍵管理システムを使用してください。
- アルゴリズムの選択:MD5、SHA1 など、既知の安全でないアルゴリズムの使用は避けてください。
- **初期化ベクトル(IV)**:対称暗号化では、暗号化のたびに異なる IV を使用する必要があります。
- 暗号学的パラメータ:十分に長い鍵長を使用してください(AES-128 ではなく AES-256 など)。
実際の適用シナリオ
- パスワードの保存:ハッシュアルゴリズムを使用してユーザーのパスワードを保存する
- データ転送の暗号化:ネットワーク転送中のデータを保護する
- API 署名の検証:API リクエストの完全性を保証する
- JWT トークン:JSON Web Tokens を生成および検証する
- ファイルの整合性チェック:ダウンロードしたファイルのハッシュ値を検証する
まとめ
Node.js のcryptoモジュールは強力な暗号化機能を提供し、安全なアプリケーションを構築するための重要なツールです。ハッシュ、暗号化、署名などの機能を適切に使用することで、開発者はデータの安全性を効果的に保護できます。使用時には、必ずセキュリティのベストプラクティスに従い、適切なアルゴリズムとパラメータを選択してください。
より複雑なセキュリティ要件には、専用の暗号化ライブラリ(例:bcrypt、argon2など)を使用することを検討できます。これらは特定の用途向けに最適化されています。