crypto-js vs hash.js vs sha.js vs sha1
JavaScript 環境におけるハッシュ関数ライブラリの選定とアーキテクチャ
crypto-jshash.jssha.jssha1類似パッケージ:

JavaScript 環境におけるハッシュ関数ライブラリの選定とアーキテクチャ

crypto-jshash.jssha.jssha1 は、JavaScript 環境でデータ整合性の検証やパスワードハッシュ化などに用いられる暗号学的ハッシュ関数を提供するライブラリです。crypto-js は SHA-1 から SHA-3 までを含む包括的な暗号スイートであり、ブラウザと Node.js の両方で動作します。hash.js は純粋な JavaScript 実装に特化し、環境依存を排除した軽量なソリューションです。sha.js は Node.js のコアモジュール crypto と互換性のあるストリーミング API を提供し、大規模データの処理に適しています。一方、sha1 は SHA-1 アルゴリズムのみに焦点を当てた単機能パッケージですが、現代のセキュリティ基準では推奨されません。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
crypto-js016,396487 kB2783年前MIT
hash.js0324-148年前MIT
sha.js029766.1 kB161年前(MIT AND BSD-3-Clause)
sha10107-011年前BSD-3-Clause

JavaScript ハッシュライブラリ完全比較:crypto-js vs hash.js vs sha.js vs sha1

JavaScript でデータをハッシュ化する際、どのライブラリを選ぶべきかは「実行環境」「データサイズ」「必要なアルゴリズム」によって大きく変わります。crypto-jshash.jssha.jssha1 はそれぞれ異なる設計思想を持っており、誤った選択をするとパフォーマンスの低下やセキュリティリスク、あるいは不要なバンドルサイズの増加を招きます。

ここでは、各ライブラリの内部動作と実装パターンを深掘りし、実際の開発現場でどう使い分けるべきかを解説します。

🛡️ セキュリティとアルゴリズムの対応範囲

まず前提として、sha1 パッケージは新しいプロジェクトで使用すべきではありません。SHA-1 アルゴリズム自体が衝突耐性を失っており、セキュリティ要件を満たさないためです。

crypto-js は、SHA-1、SHA-256、SHA-512、SHA-3、MD5 などをすべて含む「オールインワン」パッケージです。一つのインポートで様々なアルゴリズムを切り替えられるため、仕様が固まっていない初期段階や、複数のアルゴリズムを試す場合に便利です。

// crypto-js: 様々なアルゴリズムを統一された API で利用可能
const CryptoJS = require('crypto-js');

const hash256 = CryptoJS.SHA256('message').toString();
const hash512 = CryptoJS.SHA512('message').toString();
const hashSha3 = CryptoJS.SHA3('message').toString();

hash.js は、純粋な JavaScript 実装として SHA-256 や SHA-512 などを提供します。アルゴリズムの種類は crypto-js より絞られていますが、主要なものは網羅しており、実装の軽快さが特徴です。

// hash.js: 主要な SHA アルゴリズムを提供
const hash = require('hash.js');

const hash256 = hash.sha256().update('message').digest('hex');
const hash512 = hash.sha512().update('message').digest('hex');
// SHA-3 なども対応していますが、API はオブジェクトチェーン形式

sha.js は、名前の通り SHA ファミリーに特化していますが、その実装は Node.js の標準 crypto モジュールに合わせることを意識しています。SHA-1 も含まれますが、これは互換性のためであり、使用は避けるべきです。

// sha.js: Node.js の crypto モジュールに近い API
const SHA256 = require('sha.js/sha256');

const hash = new SHA256();
hash.update('message');
const result = hash.digest('hex');

sha1 は SHA-1 のみを提供します。機能が限定されているためバンドルサイズは小さいですが、セキュリティリスクを許容できる特殊なケース以外では採用理由が見当たりません。

// sha1: SHA-1 のみ(非推奨)
const sha1 = require('sha1');

// 脆弱なアルゴリズムのため、セキュリティ用途には使用不可
const hash = sha1('message'); 

🚀 実行モデル:一括処理 vs ストリーミング処理

ハッシュ計算のパフォーマンスは、データの扱い方(一括かストリームか)で劇的に変わります。特に数 MB 以上のファイルを扱う場合、この違いがメモリ枯渇や処理速度のボトルネックになります。

crypto-js は、基本的にデータを一度にメモリ上に展開して処理する「一括処理」モデルです。API がシンプルで CryptoJS.SHA256(data) と書くだけで済むため、テキストや小さな JSON データを扱うフロントエンド処理には最適です。

// crypto-js: 一括処理向け。大きなデータだとメモリを圧迫する可能性あり
const CryptoJS = require('crypto-js');

const largeData = getLargeString(); // 大きな文字列
const hash = CryptoJS.SHA256(largeData).toString();

hash.js も同様に、更新メソッド (update) を持っていますが、基本的にはバッファを蓄積して処理するスタイルです。ただし、純粋な JS 実装であるため、バイナリデータの扱いが柔軟で、ブラウザでの動作が安定しています。

// hash.js: チャンクごとの更新は可能だが、ストリーム変換は自前で行う必要がある
const hash = require('hash.js');
const hasher = hash.sha256();

hasher.update('chunk1');
hasher.update('chunk2');
const result = hasher.digest('hex');

sha.js の真価は「ストリーミング処理」にあります。Node.js の stream モジュールと相性が良く、ファイルをディスクから読みながらハッシュを計算できるため、巨大なファイルを扱ってもメモリ使用量が一定に保たれます。

// sha.js: Node.js の Stream API と完全に互換性あり
const fs = require('fs');
const SHA256 = require('sha.js/sha256');
const { pipeline } = require('stream');

const readStream = fs.createReadStream('large-file.zip');
const hashStream = new SHA256();

// ファイルをすべてメモリに載せず、流しながらハッシュ計算
pipeline(readStream, hashStream, (err) => {
  if (!err) console.log(hashStream.digest('hex'));
});

sha1 は単純な関数呼び出しモデルであり、ストリーミング対応はされていません。大量のデータを扱うには不向きです。

// sha1: 一括処理のみ対応
const sha1 = require('sha1');
const hash = sha1(largeBuffer); // 全データをメモリ上に持つ必要がある

🌐 環境依存とバンドル事情

フロントエンド開発において、「Node.js の機能に依存していないか」は重要な選定基準です。

crypto-js はブラウザと Node.js の両方を最初から意識して作られています。特別な設定なしに Webpack や Vite で動作し、グローバルオブジェクトへの依存も少ないため、最も導入障壁が低いです。

// crypto-js: 環境を問わずそのまま動作
import CryptoJS from 'crypto-js';
// ブラウザでも Node.js でも同じように動く

hash.js は「Pure JavaScript」を謳っており、Node.js の buffercrypto モジュールへの依存を極力排除しています。これにより、Web Workers や Service Workers、あるいは非常に制限されたランタイム環境でも確実に動作します。

// hash.js: 外部依存が少なく、どんな JS 環境でも安定して動作
import hash from 'hash.js';
// Node.js 固有のモジュールを必要としないため、フロントエンドで安心

sha.js は Node.js の Buffer クラスに強く依存しています。ブラウザで使う場合、Webpack などで buffer ポリフィルを適切に設定しないと動作しないことがあります。Node.js ベースのツールチェーンの中では強力ですが、フロントエンド単体で使うには設定コストがかかります。

// sha.js: ブラウザで使うには Buffer のポリフィルが必要になることが多い
import SHA256 from 'sha.js/sha256';
// Node.js 環境以外では、global.Buffer 等の準備が必要

sha1 も比較的軽量ですが、現代のフロントエンドビルドツールにおいては、よりメンテナンスが活発で機能豊富な alternatives があるため、あえてこれを選ぶメリットは薄れています。

🏗️ 実装スタイルの比較

各ライブラリの API デザインは、開発者の思考プロセスに影響を与えます。

crypto-js は「関数呼び出し」スタイルです。引数を渡して結果をもらうという、最も直感的な形式を取っています。

// crypto-js: 関数呼び出しスタイル
const hash = CryptoJS.SHA256('data').toString(CryptoJS.enc.Hex);

hash.jssha.js は「ビルダー(チェーン)」スタイルです。インスタンスを作成し、データを追加し、最後に確定させるという流れです。これは複数のデータを段階的にハッシュ化する際に明確な意図を示せます。

// hash.js / sha.js: ビルダーパターン
const hasher = new SHA256(); // または hash.sha256()
hasher.update('part1');
hasher.update('part2');
const hash = hasher.digest('hex');

sha1 は単純な関数呼び出しです。

// sha1: 単純な関数
const hash = sha1('data');

📊 選定ガイド:ユースケース別ベストプラクティス

実際のプロジェクトでは、以下のような基準で選定するのが賢明です。

要件推奨パッケージ理由
手軽に導入したいcrypto-jsAPI が簡単で、環境依存が少ない。
大規模ファイル処理 (Node.js)sha.jsストリーム処理に対応し、メモリ効率が最高。
純粋な JS 実装が必要hash.jsNode.js 依存がなく、Web Workers 等でも安全に動作。
レガシー対応・学習用sha1SHA-1 専用だが、セキュリティ用途には非推奨。

💡 結論:現代のフロントエンドアーキテクチャにおいて

セキュリティとパフォーマンスのバランスを考慮すると、標準的なフロントエンドアプリケーションでは crypto-js または hash.js を採用するのが無難です。

crypto-js はその利便性から、多くのプロジェクトでデファクトスタンダードとなっています。一方、バンドルサイズや環境の純粋性を厳密に管理したい場合には hash.js が優れた選択肢となります。

sha.js は、Node.js サーバーサイドでファイルを処理するバックエンドエンジニアにとっては不可欠なツールですが、フロントエンドのバンドルに含める際にはポリフィル等のコストを考慮する必要があります。

最後に繰り返しになりますが、sha1 パッケージをセキュリティクリティカルな用途で使用することは避けてください。SHA-256 などを提供する他のライブラリへ移行することが、プロフェッショナルとしての責任ある判断です。

技術選定においては、「できること」だけでなく「何のために使うか」という文脈を常に意識し、プロジェクトの長期維持性を損なわない選択を行いましょう。

選び方: crypto-js vs hash.js vs sha.js vs sha1

  • crypto-js:

    ブラウザと Node.js で同じコードベースを動かす必要があり、SHA-256 や AES など多様なアルゴリズムを単一の依存関係で賄いたい場合に選択します。API がシンプルで導入が容易ですが、大規模なデータを扱う際のストリーミング処理には向いていません。包括的な機能セットが必要なプロジェクトや、プロトタイピング段階で迅速に実装したい場合に最適です。

  • hash.js:

    Node.js の crypto モジュールに依存せず、純粋な JavaScript 実装のみで環境を選ばずに動作させる必要がある場合に選択します。バンドルサイズを最小限に抑えつつ、SHA-256 などの主要アルゴリズムを安定して利用したいフロントエンドアプリケーションに適しています。外部ネイティブモジュールとの連携問題を避けたい場合の堅実な選択肢です。

  • sha.js:

    Node.js 環境で大規模なファイルやストリームデータを処理する必要があり、メモリ効率を重視する場合に選択します。Node.js 標準の crypto.createHash と類似したストリーミングインターフェースを提供するため、バックエンド開発者にとって親和性が高いです。ブラウザでの利用も可能ですが、主にサーバーサイドでの高性能なハッシュ計算を目的とする場合に真価を発揮します。

  • sha1:

    レガシーシステムとの互換性維持のため、あるいは学習目的で SHA-1 アルゴリズムの挙動を確認したい場合にのみ限定的に使用します。セキュリティ上の脆弱性が知られているため、新しいプロジェクトやパスワード保存、データ整合性検証などの重要な用途では絶対に使用すべきではありません。現代のアプリケーションでは、より安全な SHA-256 等を提供する他のパッケージへの移行を強く推奨します。

crypto-js のREADME

crypto-js

JavaScript library of crypto standards.

Discontinued

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.

Node.js (Install)

Requirements:

  • Node.js
  • npm (Node.js package manager)
npm install crypto-js

Usage

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"));

Client (browser)

Requirements:

  • Node.js
  • Bower (package manager for frontend)
bower install crypto-js

Usage

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"));
});

Usage without RequireJS

<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>

API

See: https://cryptojs.gitbook.io/docs/

AES Encryption

Plain text encryption

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'

Object encryption

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}]

List of modules

  • crypto-js/core
  • crypto-js/x64-core
  • crypto-js/lib-typedarrays

  • crypto-js/md5
  • crypto-js/sha1
  • crypto-js/sha256
  • crypto-js/sha224
  • crypto-js/sha512
  • crypto-js/sha384
  • crypto-js/sha3
  • crypto-js/ripemd160

  • crypto-js/hmac-md5
  • crypto-js/hmac-sha1
  • crypto-js/hmac-sha256
  • crypto-js/hmac-sha224
  • crypto-js/hmac-sha512
  • crypto-js/hmac-sha384
  • crypto-js/hmac-sha3
  • crypto-js/hmac-ripemd160

  • crypto-js/pbkdf2

  • crypto-js/aes
  • crypto-js/tripledes
  • crypto-js/rc4
  • crypto-js/rabbit
  • crypto-js/rabbit-legacy
  • crypto-js/evpkdf

  • crypto-js/format-openssl
  • crypto-js/format-hex

  • crypto-js/enc-latin1
  • crypto-js/enc-utf8
  • crypto-js/enc-hex
  • crypto-js/enc-utf16
  • crypto-js/enc-base64

  • crypto-js/mode-cfb
  • crypto-js/mode-ctr
  • crypto-js/mode-ctr-gladman
  • crypto-js/mode-ofb
  • crypto-js/mode-ecb

  • crypto-js/pad-pkcs7
  • crypto-js/pad-ansix923
  • crypto-js/pad-iso10126
  • crypto-js/pad-iso97971
  • crypto-js/pad-zeropadding
  • crypto-js/pad-nopadding

Release notes

4.2.0

Change default hash algorithm and iteration's for PBKDF2 to prevent weak security by using the default configuration.

Custom KDF Hasher

Blowfish support

4.1.1

Fix module order in bundled release.

Include the browser field in the released package.json.

4.1.0

Added url safe variant of base64 encoding. 357

Avoid webpack to add crypto-browser package. 364

4.0.0

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.

3.3.0

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.

3.2.1

The usage of the native crypto module has been fixed. The import and access of the native crypto module has been improved.

3.2.0

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!

3.1.x

The 3.1.x are based on the original CryptoJS, wrapped in CommonJS modules.