crypto-js、js-md5、md5 は、JavaScript 環境で MD5 ハッシュ値を生成するためのライブラリです。これらはファイルの整合性確認や、セキュリティを必要としない識別子の生成などに使用されます。crypto-js は多様な暗号アルゴリズムを含むスイートであり、js-md5 と md5 は MD5 に特化した軽量な実装です。ただし、MD5 は暗号学的に安全ではないため、パスワード保存やデジタル署名には使用しないでください。
JavaScript でハッシュ値を生成する際、crypto-js、js-md5、md5 という 3 つの主要な選択肢があります。これらはすべて MD5 アルゴリズムを実装していますが、設計思想、API の使い勝手、そしてメンテナンス状況に違いがあります。特に重要なのは、MD5 が現代のセキュリティ基準では「破綻している」とみなされている点です。パスワードや機密データの保護には絶対に使用せず、ファイルのチェックサムや一時的な識別子生成などに限定して使用しましょう。
まず前提として、MD5 は衝突耐性が破られており、セキュリティ目的での使用は推奨されません。
bcrypt や argon2 を使用します。SHA-256 以上を使用します。この前提を理解した上で、技術的な実装違いを比較します。
ライブラリごとの最大の違いは、どのように関数を呼び出すかという点です。
crypto-js はオブジェクト指向的な名前空間構造を採用しています。
CryptoJS グローバルオブジェクト、またはモジュール経由でアクセスします。// crypto-js: 名前空間経由でアクセス
import CryptoJS from 'crypto-js';
const hash = CryptoJS.MD5("message").toString();
console.log(hash);
js-md5 はシンプルな関数エクスポートを提供します。
// js-md5: 関数として直接呼び出し
import md5 from 'js-md5';
const hash = md5("message");
console.log(hash);
md5 も同様にシンプルな関数インターフェースです。
js-md5 と非常によく似ていますが、パッケージ由来が異なります。// md5: 関数として直接呼び出し
import md5 from 'md5';
const hash = md5("message");
console.log(hash);
日本語や絵文字を含む UTF-8 文字列を扱う際、ライブラリによる扱いの違いがバグの原因になることがあります。
crypto-js は内部で WordArray を使用します。
.toString() で Hex 文字列に、.toString(CryptoJS.enc.Base64) で Base64 になります。// crypto-js: 出力形式の指定
import CryptoJS from 'crypto-js';
const hex = CryptoJS.MD5("日本語").toString();
const base64 = CryptoJS.MD5("日本語").toString(CryptoJS.enc.Base64);
js-md5 は UTF-8 処理に強く、出力形式もメソッドで選べます。
md5.hex()、md5.array() など、用途に合わせて使い分けられます。// js-md5: 出力形式のメソッド
import md5 from 'js-md5';
const hex = md5.hex("日本語");
const array = md5.array("日本語");
md5 は基本的な文字列ハッシュに焦点を当てています。
// md5: 標準出力
import md5 from 'md5';
const hex = md5("日本語");
// Base64 等への変換は別途ライブラリが必要な場合あり
長期プロジェクトでは、ライブラリのメンテナンス状況が重要です。
crypto-js は非常に広く使されており、更新も継続されています。
js-md5 は MD5 専用として活発に维护されています。
md5 は歴史が長いですが、更新頻度は低めです。
js-md5 の方が安心できる選択肢です。| 特徴 | crypto-js | js-md5 | md5 |
|---|---|---|---|
| API 形式 | 名前空間 (CryptoJS.MD5) | 関数 (md5()) | 関数 (md5()) |
| 出力変換 | .toString() 必要 | 直接文字列返却 | 直接文字列返却 |
| UTF-8 対応 | 良好 | 非常に良好 | 良好 |
| 機能範囲 | 多様な暗号アルゴリズム | MD5 専用 | MD5 専用 |
| メンテナンス | 活発 | 活発 | 緩やか |
| 推奨用途 | 包括的な暗号化が必要な場合 | MD5 専用で最新性を求める場合 | 既存プロジェクトの維持 |
crypto-js は、MD5 だけでなく SHA や AES なども必要になる大規模なセキュリティ実装において威力を発揮します — すでにプロジェクトで採用されているならそのまま使うのが合理です。
js-md5 は、MD5 hashing 専用として最もバランスが取れています — UTF-8 処理が確実で、API もシンプルです。新規で MD5 が必要な場合はこれを第一候補にしてください。
md5 は、単純さこそが命という古いプロジェクトとの互換性維持に適しています — ただし、メンテナンスの観点から新規採用は慎重になるべきです。
繰り返しになりますが、セキュリティが重要な場面では MD5 自体の使用を避けてください。それ以外の用途では、プロジェクトの要件に合わせて上記の基準で選定しましょう。
SHA や AES など他の暗号アルゴリズムも同時に必要な場合は crypto-js を選定してください。既存のプロジェクトで既に導入されている場合も移行コストが低くなります。ただし、MD5 専用としてはオーバーヘッドが大きくなる点に注意が必要です。
MD5 専用で、UTF-8 文字列の扱いやパフォーマンスを重視する場合は js-md5 が適しています。ブラウザと Node.js の両方で動作し、メンテナンスも活発です。シンプルな関数呼び出しで完結するため、コードが読みやすくなります。
最もシンプルな実装で十分であり、既存のレガシーコードとの互換性を保つ必要がある場合は md5 を検討できます。ただし、他の 2 つに比べてメンテナンス頻度が低い傾向があるため、新規プロジェクトでは js-md5 の使用を推奨します。
JavaScript library of crypto standards.
Active development of CryptoJS has been discontinued. This library is no longer maintained.
Nowadays, NodeJS and modern browsers have a native Crypto module. The latest version of CryptoJS already uses the native Crypto module for random number generation, since Math.random() is not crypto-safe. Further development of CryptoJS would result in it only being a wrapper of native Crypto. Therefore, development and maintenance has been discontinued, it is time to go for the native crypto module.
Requirements:
npm install crypto-js
ES6 import for typical API call signing use case:
import sha256 from 'crypto-js/sha256';
import hmacSHA512 from 'crypto-js/hmac-sha512';
import Base64 from 'crypto-js/enc-base64';
const message, nonce, path, privateKey; // ...
const hashDigest = sha256(nonce + message);
const hmacDigest = Base64.stringify(hmacSHA512(path + hashDigest, privateKey));
Modular include:
var AES = require("crypto-js/aes");
var SHA256 = require("crypto-js/sha256");
...
console.log(SHA256("Message"));
Including all libraries, for access to extra methods:
var CryptoJS = require("crypto-js");
console.log(CryptoJS.HmacSHA1("Message", "Key"));
Requirements:
bower install crypto-js
Modular include:
require.config({
packages: [
{
name: 'crypto-js',
location: 'path-to/bower_components/crypto-js',
main: 'index'
}
]
});
require(["crypto-js/aes", "crypto-js/sha256"], function (AES, SHA256) {
console.log(SHA256("Message"));
});
Including all libraries, for access to extra methods:
// Above-mentioned will work or use this simple form
require.config({
paths: {
'crypto-js': 'path-to/bower_components/crypto-js/crypto-js'
}
});
require(["crypto-js"], function (CryptoJS) {
console.log(CryptoJS.HmacSHA1("Message", "Key"));
});
<script type="text/javascript" src="path-to/bower_components/crypto-js/crypto-js.js"></script>
<script type="text/javascript">
var encrypted = CryptoJS.AES(...);
var encrypted = CryptoJS.SHA256(...);
</script>
See: https://cryptojs.gitbook.io/docs/
var CryptoJS = require("crypto-js");
// Encrypt
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123').toString();
// Decrypt
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
var originalText = bytes.toString(CryptoJS.enc.Utf8);
console.log(originalText); // 'my message'
var CryptoJS = require("crypto-js");
var data = [{id: 1}, {id: 2}]
// Encrypt
var ciphertext = CryptoJS.AES.encrypt(JSON.stringify(data), 'secret key 123').toString();
// Decrypt
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
var decryptedData = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
console.log(decryptedData); // [{id: 1}, {id: 2}]
crypto-js/corecrypto-js/x64-corecrypto-js/lib-typedarrayscrypto-js/md5crypto-js/sha1crypto-js/sha256crypto-js/sha224crypto-js/sha512crypto-js/sha384crypto-js/sha3crypto-js/ripemd160crypto-js/hmac-md5crypto-js/hmac-sha1crypto-js/hmac-sha256crypto-js/hmac-sha224crypto-js/hmac-sha512crypto-js/hmac-sha384crypto-js/hmac-sha3crypto-js/hmac-ripemd160crypto-js/pbkdf2crypto-js/aescrypto-js/tripledescrypto-js/rc4crypto-js/rabbitcrypto-js/rabbit-legacycrypto-js/evpkdfcrypto-js/format-opensslcrypto-js/format-hexcrypto-js/enc-latin1crypto-js/enc-utf8crypto-js/enc-hexcrypto-js/enc-utf16crypto-js/enc-base64crypto-js/mode-cfbcrypto-js/mode-ctrcrypto-js/mode-ctr-gladmancrypto-js/mode-ofbcrypto-js/mode-ecbcrypto-js/pad-pkcs7crypto-js/pad-ansix923crypto-js/pad-iso10126crypto-js/pad-iso97971crypto-js/pad-zeropaddingcrypto-js/pad-nopaddingChange default hash algorithm and iteration's for PBKDF2 to prevent weak security by using the default configuration.
Custom KDF Hasher
Blowfish support
Fix module order in bundled release.
Include the browser field in the released package.json.
Added url safe variant of base64 encoding. 357
Avoid webpack to add crypto-browser package. 364
This is an update including breaking changes for some environments.
In this version Math.random() has been replaced by the random methods of the native crypto module.
For this reason CryptoJS might not run in some JavaScript environments without native crypto module. Such as IE 10 or before or React Native.
Rollback, 3.3.0 is the same as 3.1.9-1.
The move of using native secure crypto module will be shifted to a new 4.x.x version. As it is a breaking change the impact is too big for a minor release.
The usage of the native crypto module has been fixed. The import and access of the native crypto module has been improved.
In this version Math.random() has been replaced by the random methods of the native crypto module.
For this reason CryptoJS might does not run in some JavaScript environments without native crypto module. Such as IE 10 or before.
If it's absolute required to run CryptoJS in such an environment, stay with 3.1.x version. Encrypting and decrypting stays compatible. But keep in mind 3.1.x versions still use Math.random() which is cryptographically not secure, as it's not random enough.
This version came along with CRITICAL BUG.
DO NOT USE THIS VERSION! Please, go for a newer version!
The 3.1.x are based on the original CryptoJS, wrapped in CommonJS modules.