sha.js vs crypto-js vs js-sha256 vs sha256
フロントエンドでのSHA-256ハッシュ計算ライブラリ選定ガイド
sha.jscrypto-jsjs-sha256sha256類似パッケージ:

フロントエンドでのSHA-256ハッシュ計算ライブラリ選定ガイド

crypto-jsjs-sha256sha.jssha256 はすべて JavaScript 環境で SHA-256 ハッシュを生成するための npm パッケージですが、設計思想や使用方法、依存関係、メンテナンス状況に大きな違いがあります。これらのライブラリは、パスワードのハッシュ化、データ整合性チェック、署名生成などのセキュリティ関連タスクで利用されることが多く、フロントエンド開発者が軽量かつ安全な実装を選ぶ際に重要な選択肢となります。

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

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
sha.js20,036,38229866.1 kB161年前(MIT AND BSD-3-Clause)
crypto-js17,159,42916,394487 kB2793年前MIT
js-sha2564,325,19296589.9 kB320時間前MIT
sha25680,87448-511年前-

フロントエンドでの SHA-256 ハッシュ計算:crypto-js vs js-sha256 vs sha.js vs sha256

フロントエンドで SHA-256 を使う理由はさまざまです — パスワードのクライアント側ハッシュ化、ファイルの整合性チェック、署名付きリクエストの生成など。しかし、npm 上には似たような名前のパッケージが複数存在し、どれを選ぶべきか迷う開発者も多いでしょう。ここでは、crypto-jsjs-sha256sha.js、そして非推奨の sha256 の4つを、実際のコードと使い勝手を中心に比較します。

⚠️ 非推奨パッケージの確認:sha256 は使わない

まず最初に明確にしておきます:sha256 パッケージは公式に非推奨(deprecated)です。npm ページには「Use js-sha256 instead」と明記されており、GitHub リポジトリもアーカイブ済みです。このパッケージは新しいプロジェクトで使用すべきではありません。

// ❌ sha256 — 非推奨のため使用禁止
import sha256 from 'sha256';
const hash = sha256('hello'); // 動作はするが、セキュリティアップデートなし

代わりに、後述する js-sha256 を使うことで、同じ API で安全かつメンテナンスされた実装を利用できます。

🔐 基本的な SHA-256 計算:シンプルさ vs 機能性

js-sha256:最小限で高速

js-sha256 は SHA-256 に特化しており、API が非常にシンプルです。文字列や Uint8Array を直接ハッシュ化でき、戻り値は16進数文字列です。

// ✅ js-sha256
import { sha256 } from 'js-sha256';
const hash = sha256('hello');
console.log(hash); // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'

オブジェクト指向スタイルもサポートされており、ストリーム処理も可能です。

const hasher = sha256.create();
hasher.update('hel');
hasher.update('lo');
console.log(hasher.hex()); // 同じ結果

crypto-js:多機能だが重め

crypto-js は SHA-256 以外にも多数の暗号アルゴリズムを提供します。ただし、全体をインポートすると不要なコードがバンドルに含まれるため、個別モジュールのインポートが推奨されます。

// ✅ crypto-js(個別インポート)
import sha256 from 'crypto-js/sha256';
import encHex from 'crypto-js/enc-hex';

const hash = sha256('hello');
console.log(hash.toString(encHex)); // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'

注意点として、crypto-js の戻り値は WordArray オブジェクトであり、文字列にするには .toString() とエンコーダ(例: encHex)が必要です。これは学習コストを少し高めます。

sha.js:Node.js 互換の柔軟性

sha.js は Node.js の crypto.createHash('sha256') と似たインターフェースを持ち、ストリーム処理に強いです。

// ✅ sha.js
import { sha256 } from 'sha.js';

const hash = sha256().update('hello').digest('hex');
console.log(hash); // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'

update() を複数回呼び出せるため、大容量データをチャンク単位で処理するのに適しています。

📦 入力データの扱い:文字列、バイト配列、TypedArray

各ライブラリは異なる入力形式をサポートしています。

文字列(UTF-8)

// js-sha256
sha256('こんにちは');

// crypto-js
sha256('こんにちは').toString(encHex);

// sha.js
sha256().update('こんにちは').digest('hex');

すべて問題なく動作しますが、内部エンコーディングはいずれも UTF-8 です。

Uint8Array / ArrayBuffer

バイナリデータ(例: ファイルの Blob)をハッシュ化する場合:

// js-sha256
const uint8 = new TextEncoder().encode('hello');
sha256(uint8);

// crypto-js
import WordArray from 'crypto-js/lib-typedarrays';
const wa = WordArray.create(uint8);
sha256(wa).toString(encHex);

// sha.js
sha256().update(uint8).digest('hex');

js-sha256sha.js は直接 Uint8Array を受け入れますが、crypto-js は一旦 WordArray に変換する必要があります。この点で、バイナリ処理が多いアプリでは js-sha256sha.js の方がコードが簡潔になります。

🧩 ツリーシェイキングとバンドルサイズ

  • js-sha256:ESM 対応で、import { sha256 } とすれば SHA-256 だけがバンドルされます。極めて軽量。
  • sha.js:CommonJS が基本ですが、ESM ビルドも提供。sha256 だけをインポートすれば他のアルゴリズムは含まれません。
  • crypto-js:個別モジュール(例: crypto-js/sha256)をインポートしないと、全アルゴリズムがバンドルされてしまいます。

たとえば、Vite や Webpack でビルドする場合、js-sha256 は最も小さい出力サイズを実現します。

🔄 ストリーム処理(逐次更新)

大規模データやネットワークストリームをハッシュ化する必要がある場合:

// js-sha256
const hasher = sha256.create();
hasher.update(chunk1);
hasher.update(chunk2);
const result = hasher.hex();

// sha.js
const hasher = sha256();
hasher.update(chunk1);
hasher.update(chunk2);
const result = hasher.digest('hex');

// crypto-js
// ストリーム処理は非対応。一度に全データを渡す必要あり。

crypto-js は逐次更新に対応していないため、ストリーム処理が必要なら js-sha256 または sha.js を選ぶ必要があります。

🧪 TypeScript サポート

  • js-sha256:組み込みの型定義があり、import { sha256 } from 'js-sha256' で即時利用可能。
  • sha.js:DefinitelyTyped による @types/sha.js が必要。
  • crypto-js:組み込み型定義あり。

TypeScript プロジェクトでは、追加の型定義インストール不要という点で js-sha256 が有利です。

📌 まとめ:どう選ぶべきか

パッケージ推奨シナリオ
js-sha256SHA-256 だけが必要で、軽量・シンプル・TypeScript 対応を求める場合。フロントエンド向けに最適化されています。
sha.jsNode.js とのコード共有が必要、または複数の SHA アルゴリズム(SHA-1, SHA-512 など)を将来的に使う可能性がある場合。ストリーム処理も柔軟。
crypto-jsSHA-256 以外にも AES 暗号化や HMAC など複数の暗号機能が必要な場合。ただし、個別モジュールのインポートを忘れずに。
sha256非推奨。新規プロジェクトでは絶対に使用しないでください。

💡 最終的なアドバイス

ほとんどのフロントエンドプロジェクトでは、js-sha256 が最良の選択肢です。理由は3つ:

  1. 軽量 — SHA-256 に特化しているため、バンドルサイズが最小。
  2. 使いやすい — 直感的な API で、文字列や Uint8Array をそのまま渡せる。
  3. 安全 — 現在もアクティブにメンテナンスされており、TypeScript サポートも完備。

一方、Node.js との共通コードを書く必要がある、あるいは将来的に SHA-384 や SHA-512 に拡張する可能性があるなら、sha.js を検討してください。crypto-js は「他の暗号機能も必要」でない限り、オーバースペックです。

そして、もう一度強調します:sha256 は使わないでください

選び方: sha.js vs crypto-js vs js-sha256 vs sha256

  • sha.js:

    sha.js は Node.js 標準の crypto モジュールと互換性のあるインターフェースを持ち、SHA-1 から SHA-512 まで幅広いアルゴリズムをサポートします。Node.js とのコード共有や、複数の SHA ファミリーが必要なプロジェクトに向いています。ストリーム処理も可能で、大規模データのハッシュ計算に柔軟性があります。

  • crypto-js:

    crypto-js は AES、HMAC、PBKDF2 など多数の暗号アルゴリズムを含む包括的なライブラリです。SHA-256 だけでなく他の暗号機能も必要で、かつバンドルサイズが許容できるプロジェクトに適しています。ただし、フルセットをインポートすると不要なコードが含まれるため、個別モジュールのインポートが推奨されます。

  • js-sha256:

    js-sha256 は SHA-256 専用の軽量ライブラリで、API がシンプルで直感的です。TypeScript サポートも充実しており、フロントエンドで単一のハッシュ関数だけが必要な場合に最適です。ESM/CJS の両方に対応し、ツリーシェイキングにも親和性が高いです。

  • sha256:

    sha256 パッケージは非推奨(deprecated)であり、npm および GitHub で明確にその旨が記載されています。新規プロジェクトでは絶対に使用せず、代わりに js-sha256sha.js などの代替手段を検討すべきです。既存コードで使用されている場合は早急に移行を検討してください。

sha.js のREADME

sha.js

NPM Package Build Status Dependency status

js-standard-style

Node style SHA on pure JavaScript.

var shajs = require('sha.js')

console.log(shajs('sha256').update('42').digest('hex'))
// => 73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049
console.log(new shajs.sha256().update('42').digest('hex'))
// => 73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049

var sha256stream = shajs('sha256')
sha256stream.end('42')
console.log(sha256stream.read().toString('hex'))
// => 73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049

supported hashes

sha.js currently implements:

  • SHA (SHA-0) -- legacy, do not use in new systems
  • SHA-1 -- legacy, do not use in new systems
  • SHA-224
  • SHA-256
  • SHA-384
  • SHA-512

Not an actual stream

Note, this doesn't actually implement a stream, but wrapping this in a stream is trivial. It does update incrementally, so you can hash things larger than RAM, as it uses a constant amount of memory (except when using base64 or utf8 encoding, see code comments).

Acknowledgements

This work is derived from Paul Johnston's A JavaScript implementation of the Secure Hash Algorithm.

LICENSE MIT AND BSD-3-Clause