ES6とTypeScriptと互換性のある暗号化アルゴリズムライブラリ
インストール:
yarn add crypto-es
node.jsプロジェクトでは、commonjsのecmascriptモジュールを使用することをお勧めします。
// package.json
{
"type": "module"
}
その後、暗号をインポートできます。
import CryptoES from 'crypto-es';
const rst = CryptoES.MD5("Message").toString();
または、パッケージの重量を減らすために関数を部分的にインポートします。
import { MD5 } from 'crypto-es/lib/md5.js';
const rst = MD5("Message").toString();
このライブラリのすべてのファイルには、独自の.d.tsファイルが現在あるため、タイプスクリプトプロジェクトで単一のアルゴリズムファイルを部分的にインポートすることができます。
Cryptojsとまったく同じです
MD5
MD5は広く使用されているハッシュ機能です。さまざまなセキュリティアプリケーションで使用されており、ファイルの整合性を確認するためにも一般的に使用されています。ただし、MD5は衝突抵抗性ではなく、SSL証明書やこのプロパティに依存するデジタル署名などのアプリケーションには適していません。
const hash = CryptoES.MD5("Message");
SHA-1
SHAハッシュ機能は、国家安全保障局(NSA)によって設計されました。 SHA-1は、既存のSHAハッシュ機能の中で最も確立されており、さまざまなセキュリティアプリケーションとプロトコルで使用されています。しかし、SHA-1の衝突抵抗は、新しい攻撃が発見または改善されるにつれて弱体化しています。
const hash = CryptoES.SHA1("Message");
SHA-2
SHA-256は、SHA-2セットの4つのバリアントの1つです。 SHA-1ほど広く使用されていませんが、より良いセキュリティを提供するようです。
const hash = CryptoES.SHA256("Message");
SHA-512はSHA-256とほぼ同じですが、32ではなく64ビットの単語で動作します。
const hash = CryptoES.SHA512("Message");
CryptoesはSHA-224とSHA-384もサポートしています。SHA-384は、それぞれSHA-256とSHA-512の切り捨てられたバージョンですが、切り捨てられたバージョンです。
SHA-3
SHA-3は、64の競合デザインが評価された新しい暗号化ハッシュアルゴリズムを選択するための5年間の競争の勝者です。
注:この実装をSHA-3と名付けたとき、私は間違いを犯しました。 Keccak [c = 2d]という名前を付ける必要があります。 SHA-3関数のそれぞれは、NISTがSHA-3競技の勝者として選択したKeccakアルゴリズムのインスタンスに基づいていますが、これらのSHA-3関数はKeccakと同一のハッシュを生成しません。
const hash = CryptoES.SHA3("Message");
SHA-3は、224、256、384、または512ビットのいずれかのハッシュ長を出力するように構成できます。デフォルトは512ビットです。
const hash = CryptoES.SHA3("Message", { outputLength: 512 });
const hash = CryptoES.SHA3("Message", { outputLength: 384 });
const hash = CryptoES.SHA3("Message", { outputLength: 256 });
const hash = CryptoES.SHA3("Message", { outputLength: 224 });
RIPEMD-160
const hash = CryptoES.RIPEMD160("Message");
ハッシュアルゴリズムは、cryptoes.lib.wordarrayの文字列またはインスタンスのいずれかを受け入れます。 WordArrayオブジェクトは、32ビット単語の配列を表します。文字列を渡すと、UTF-8としてエンコードされたワードアレイに自動的に変換されます。
戻ってきたハッシュはまだ文字列ではありません。ワードアレイオブジェクトです。文字列コンテキストでWordArrayオブジェクトを使用すると、16進ストリングに自動的に変換されます。
const hash = CryptoES.SHA256("Message");
alert(typeof hash); // object
alert(hash); // 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
ToStringメソッドを明示的に呼び出してエンコーダーを渡すことにより、WordArrayオブジェクトを他の形式に変換できます。
const hash = CryptoES.SHA256("Message");
alert(hash.toString(CryptoES.enc.Base64)); // L3dmip37+NWEi57rSnFFypTG7ZI25Kdz9tyvpRMrL5E= alert(hash.toString(CryptoES.enc.Latin1)); // /wf��ûøÕ���ëJqEÊ�Æí�6ä§söܯ¥�+/�
alert(hash.toString(CryptoES.enc.Hex)); // 2f77668a9dfbf8d5848b9eeb4a7145ca94c6ed9236e4a773f6dcafa5132b2f91
const sha256 = CryptoES.algo.SHA256.create();
sha256.update("Message Part 1");
sha256.update("Message Part 2");
sha256.update("Message Part 3");
const hash = sha256.finalize();
Keyed-Hashメッセージ認証コード(HMAC)は、暗号化ハッシュ関数を使用したメッセージ認証のメカニズムです。
HMACは、繰り返しの暗号化ハッシュ関数と組み合わせて使用できます。
const hash = CryptoES.HmacMD5("Message", "Secret Passphrase");
const hash = CryptoES.HmacSHA1("Message", "Secret Passphrase");
const hash = CryptoES.HmacSHA256("Message", "Secret Passphrase");
const hash = CryptoES.HmacSHA512("Message", "Secret Passphrase");
const hmac = CryptoES.algo.HMAC.create(CryptoES.algo.SHA256, "Secret Passphrase");
hmac.update("Message Part 1");
hmac.update("Message Part 2");
hmac.update("Message Part 3");
const hash = hmac.finalize();
PBKDF2は、パスワードベースのキー派生関数です。暗号化の多くのアプリケーションでは、ユーザーセキュリティは最終的にパスワードに依存します。通常、パスワードは暗号化キーとして直接使用できないため、一部の処理が必要です。
塩は、特定のパスワードに大きなキーセットを提供し、反復カウントはパスワードからキーを生成するコストを増加させ、それによって攻撃の難しさも増加します。
const salt = CryptoES.lib.WordArray.random(128/8);
const key128Bits = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 128/32 });
const key256Bits = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 256/32 });
const key512Bits = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 512/32 });
const key512Bits1000Iterations = CryptoES.PBKDF2("Secret Passphrase", salt, { keySize: 512/32, iterations: 1000 });
AES
高度な暗号化標準(AES)は、米国連邦情報処理標準(FIPS)です。 15の競合デザインが評価された5年間のプロセスの後に選択されました。
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.AES.decrypt(encrypted, "Secret Passphrase");
Cryptoesは、AES-128、AES-192、およびAES-256をサポートしています。渡すキーのサイズによってバリアントを選択します。パスフレーズを使用すると、256ビットキーが生成されます。
デス、トリプルデス
DESは、暗号化の以前は支配的なアルゴリズムであり、公式の連邦情報処理標準(FIPS)として公開されました。キーサイズが小さいため、DESは現在、不安定であると考えられています。
const encrypted = CryptoES.DES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.DES.decrypt(encrypted, "Secret Passphrase");
トリプルデスは、各ブロックに3回DESを適用して、キーサイズを増やします。アルゴリズムは、この形式で安全であると考えられています。
const encrypted = CryptoES.TripleDES.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.TripleDES.decrypt(encrypted, "Secret Passphrase");
うさぎ
Rabbitは、高性能のストリーム暗号であり、Estreamポートフォリオのファイナリストです。これは、22のデザインが評価された3 1/2年のプロセスの後に選択された4つのデザインの1つです。
const encrypted = CryptoES.Rabbit.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.Rabbit.decrypt(encrypted, "Secret Passphrase");
RC4、RC4DROP
RC4は、広く使用されているストリーム暗号です。 SSLやWEPなどの一般的なプロトコルで使用されています。そのシンプルさとスピードでは注目に値しますが、アルゴリズムの歴史はセキュリティに対する自信を刺激しません。
const encrypted = CryptoES.RC4.encrypt("Message", "Secret Passphrase");
const decrypted = CryptoES.RC4.decrypt(encrypted, "Secret Passphrase");
キーストリームの最初の数バイトは、キーに関するランダムではなく、リーク情報であることが発見されました。キーストリームの初期部分を破棄することにより、この攻撃から防御できます。この変更されたアルゴリズムは、伝統的にRC4ドロップと呼ばれています。
デフォルトでは、192ワード(768バイト)が削除されますが、アルゴリズムを構成して、任意の数の単語をドロップすることができます。
const encrypted = CryptoES.RC4Drop.encrypt("Message", "Secret Passphrase");
const encrypted = CryptoES.RC4Drop.encrypt("Message", "Secret Passphrase", { drop: 3072/4 });
const decrypted = CryptoES.RC4Drop.decrypt(encrypted, "Secret Passphrase", { drop: 3072/4 });
ブローフィッシュ
Blowfishは、1993年にBruce Schneierが設計し、多くの暗号スイートと暗号化製品に含まれている対称キーブロック暗号です。 Blowfishはソフトウェアで優れた暗号化率を提供し、これまでの効果的な暗号化はこれまで発見されていません。ただし、高度な暗号化標準(AES)はより多くの注目を集めており、Schneierは最新のアプリケーションにTwofishを推奨しています。
Schneierは、Blowfishを汎用アルゴリズムとして設計しました。これは、老化DESの代替として意図され、他のアルゴリズムに関連する問題や制約がありません。当時、ブローフィッシュはリリースされていたため、他の多くのデザインは独自のものであり、特許によって妨げられているか、商業的または政府の秘密でした。 Schneierは、「Blowfishは特徴がなく、すべての国でそうであり続けるでしょう。アルゴリズムはここにパブリックドメインに配置され、誰でも自由に使用できます」と述べています。
設計の顕著な機能には、キー依存S-Boxeと非常に複雑なキースケジュールが含まれます。
const ciphertext = CryptoJS.Blowfish.encrypt(message, key, cfg);
const plaintext = CryptoJS.Blowfish.decrypt(ciphertext, key, cfg);
const key = CryptoES.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
const iv = CryptoES.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');
const encrypted = CryptoES.AES.encrypt("Message", key, { iv: iv });
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase", { mode: CryptoES.mode.CFB, padding: CryptoES.pad.AnsiX923 });
暗号化は次のモードをサポートしています。
また、暗号は次のパディングスキームをサポートしています。
プレーンテキストメッセージの場合、暗号アルゴリズムはcryptoes.lib.wordarrayの文字列またはインスタンスのいずれかを受け入れます。
キーの場合、文字列を渡すと、パスフレーズとして扱われ、実際のキーとIVの導出に使用されます。または、実際のキーを表すWordArrayを渡すことができます。実際のキーを渡す場合は、実際のIVにも合格する必要があります。
ciphertextの場合、暗号アルゴリズムは、cryptoes.lib.cipherparamsの文字列またはインスタンスのいずれかを受け入れます。 Cipherparamsオブジェクトは、IV、塩、生の暗号文自体などのパラメーターのコレクションを表します。文字列を渡すと、構成可能な形式戦略に従ってCipherparamsオブジェクトに自動的に変換されます。
復号化後に戻ってくる平文は、WordArrayオブジェクトです。詳細については、Hashersの出力を参照してください。
暗号化後に戻ってきた暗号文はまだ文字列ではありません。 Cipherparamsオブジェクトです。 Cipherparamsオブジェクトは、暗号化中に使用されるすべてのパラメーターにアクセスできます。文字列コンテキストでcipherparamsオブジェクトを使用すると、フォーマット戦略に従って文字列に自動的に変換されます。デフォルトはOpenSSL互換形式です。
const encrypted = CryptoES.AES.encrypt("Message", "Secret Passphrase"); alert(encrypted.key); // 74eb593087a982e2a6f5dded54ecd96d1fd0f3d44a58728cdcd40c55227522223
alert(encrypted.iv); // 7781157e2629b094f0e3dd48c4d786115
alert(encrypted.salt); // 7a25f9132ec6a8b34
alert(encrypted.ciphertext); // 73e54154a15d1beeb509d9e12f1e462a0
alert(encrypted); // U2FsdGVkX1+iX5Ey7GqLND5UFUoV0b7rUJ2eEvHkYqA=
他の暗号実装と互換性があるように、独自のフォーマットを定義できます。フォーマットは、Cipherparamsオブジェクトと暗号文字列の間に変換される2つのメソッドを備えた2つの方法を備えたオブジェクトです。
JSONのフォーマッタを書く方法は次のとおりです。
const JsonFormatter = {
stringify: function (cipherParams) { // create json object with ciphertext
const jsonObj = { ct: cipherParams.ciphertext.toString(CryptoES.enc.Base64) }; // optionally add iv and salt
if (cipherParams.iv) {
jsonObj.iv = cipherParams.iv.toString();
}
if (cipherParams.salt) {
jsonObj.s = cipherParams.salt.toString();
}
// stringify json object
return JSON.stringify(jsonObj);
},
parse: function (jsonStr) { // parse json string
const jsonObj = JSON.parse(jsonStr); // extract ciphertext from json object, and create cipher params object
const cipherParams = CryptoES.lib.CipherParams.create(
{ ciphertext: CryptoES.enc.Base64.parse(jsonObj.ct) },
); // optionally extract iv and salt
if (jsonObj.iv) {
cipherParams.iv = CryptoES.enc.Hex.parse(jsonObj.iv)
}
if (jsonObj.s) {
cipherParams.salt = CryptoES.enc.Hex.parse(jsonObj.s)
}
return cipherParams;
},
};
const encrypted = CryptoES.AES.encrypt(
"Message",
"Secret Passphrase",
{ format: JsonFormatter },
);
alert(encrypted); // {"ct":"tZ4MsEnfbcDOwqau68aOrQ==","iv":"8a8c8fd8fe33743d3638737ea4a00698","s":"ba06373c8f57179c"}
const decrypted = CryptoES.AES.decrypt(
encrypted,
"Secret Passphrase",
{ format: JsonFormatter },
);
alert(decrypted.toString(CryptoES.enc.Utf8)); // Message
const key = CryptoES.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
const iv = CryptoES.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');
const aesEncryptor = CryptoES.algo.AES.createEncryptor(key, { iv: iv });
const ciphertextPart1 = aesEncryptor.process("Message Part 1");
const ciphertextPart2 = aesEncryptor.process("Message Part 2");
const ciphertextPart3 = aesEncryptor.process("Message Part 3");
const ciphertextPart4 = aesEncryptor.finalize();
const aesDecryptor = CryptoES.algo.AES.createDecryptor(key, { iv: iv });
const plaintextPart1 = aesDecryptor.process(ciphertextPart1);
const plaintextPart2 = aesDecryptor.process(ciphertextPart2);
const plaintextPart3 = aesDecryptor.process(ciphertextPart3);
const plaintextPart4 = aesDecryptor.process(ciphertextPart4);
const plaintextPart5 = aesDecryptor.finalize();
opensslで
OpenSSLで暗号化:
openssl enc -aes-256-cbc -in infile -out outfile -pass pass:"Secret Passphrase" -e -base64
暗号で復号化する:
const decrypted = CryptoES.AES.decrypt(openSSLEncrypted, "Secret Passphrase");
暗号化は、Base64、LATIN1、HEXなどのエンコード形式からWordArrayオブジェクト、VICA VERSAに変換できます。
const words = CryptoES.enc.Base64.parse('SGVsbG8sIFdvcmxkIQ==');
const base64 = CryptoES.enc.Base64.stringify(words);
const words = CryptoES.enc.Base64url.parse('SGVsbG8sIFdvcmxkIQ==');
const base64url = CryptoES.enc.Base64.stringify(words);
const words = CryptoES.enc.Latin1.parse('Hello, World!');
const latin1 = CryptoES.enc.Latin1.stringify(words);
const words = CryptoES.enc.Hex.parse('48656c6c6f2c20576f726c6421');
const hex = CryptoES.enc.Hex.stringify(words);
const words = CryptoES.enc.Utf8.parse('?');
const utf8 = CryptoES.enc.Utf8.stringify(words);
const words = CryptoES.enc.Utf16.parse('Hello, World!');
const utf16 = CryptoES.enc.Utf16.stringify(words);
const words = CryptoES.enc.Utf16LE.parse('Hello, World!');
const utf16 = CryptoES.enc.Utf16LE.stringify(words);
WordArrayの作成者は、ArrayBufferまたはTypedArrayを受信して、暗号化のアルゴリズムが彼らに適用できるようにすることができます。
const words = CryptoES.lib.WordArray.create(new ArrayBuffer(8));
const rst = CryptoES.AES.encrypt(words, 'Secret Passphrase')
注:ArrayBufferはアルゴリズムに直接渡すことができませんでした。最初にWordArrayに変更する必要があります。
これにより、ファイルを暗号化する方が簡単です。
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function () {
const arrayBuffer = reader.result;
const words = CryptoES.lib.WordArray.create(arrayBuffer);
const rst = CryptoES.AES.encrypt(words, 'Secret Passphrase')
...
};
ログを変更します
現代のECMAScriptのRefactoring Cryptojs