NodeJS暗号化——cryptモジュール
原文を読む
暗号化プロファイル
暗号化は、暗号化された情報を取得しても、暗号化された情報が得られなくても、情報の本当の意味が分かりません.このようにして、ネットワークデータ伝送の安全性を高めます.暗号化アルゴリズムによくあるのは、ハシーアルゴリズム、HMACアルゴリズム、署名、対称性暗号化アルゴリズム、非対称性暗号化アルゴリズムです.暗号化アルゴリズムも可逆と不可逆に分けられています.例えば
ハッシュ・アルゴリズム
ハッシュアルゴリズムは、任意の長さの入力を固定長の出力に変換するためのハッシュアルゴリズムとも呼ばれ、一般的には不可逆; は、暗号化されたコンテンツの長さにかかわらず、最後に出力された結果の長さは等しくなる. コンテンツの異なる出力の結果は全く異なり、コンテンツの同じ出力の結果は全く同じである. 同じ入力が
短所:
Hmacアルゴリズム
1、Hmacアルゴリズムの使用
Hmacアルゴリズムはまた塩添加アルゴリズムとも呼ばれ、署名の完全性の破壊を阻止するためにハッシュアルゴリズムを一つの鍵と結合し、
セキュリティは
2、鍵の作成方法
openssl genrsa-out rsa_prvate.key 1024
対称性暗号化は、データを送信する際に、鍵と暗号化アルゴリズムを用いて暗号化され、データを受信する際には同じ鍵と暗号化アルゴリズムの逆アルゴリズム(復号アルゴリズム)を用いて復号される必要があり、すなわち対称性暗号化のプロセスは可逆的であり、
対称性の暗号化を使用する文字列は長さ制限があり、
短所:鍵は伝送中に入手しやすく、安全リスクがある.
非対称暗号化
非対称暗号化相も可逆的であり、対称性よりも安全であり、メッセージ送信者と受信者はローカルで鍵のペアを作成し、公開鍵と秘密鍵を互いに相手に送信し、メッセージ送信時には相手の公開鍵を使って暗号化し、相手がメッセージを受信した後に彼の秘密鍵を使って解読する.このように、公開鍵の配信中に切断されても解読できない.公開鍵の暗号化されたメッセージは、ペアの秘密鍵のみが復号されるからである.
次に、
openssl rsa-in rsa_prvate.key-pubout-out rsa_public.key
上記のコマンドは、1つの秘密鍵から対応する公開鍵を生成し、
署名する
署名は非対称性暗号と非常に類似しており、公開鍵と秘密鍵とは異なり、相手は公開鍵を用いて暗号解読検証を行い、このデータが秘密鍵の所有者から送信された元のデータであることを保証し、ネットワーク内の伝送過程では変更されていない.
また、以下のように署名コードを実装するために
署名を検証する
使用シーン:cookie署名をブラウザに返すためによく使われています.ブラウザがドメインサーバにアクセスしてクッキーを持ってきたら検証します.クッキーが改竄されるのを防ぎ、CSRFスパンが偽造を要求します.
締め括りをつける
様々な項目は、データ伝送時に情報の感度と用途に応じて異なる暗号化アルゴリズムと暗号化方式を行い、NodeJSにおいて
暗号化プロファイル
暗号化は、暗号化された情報を取得しても、暗号化された情報が得られなくても、情報の本当の意味が分かりません.このようにして、ネットワークデータ伝送の安全性を高めます.暗号化アルゴリズムによくあるのは、ハシーアルゴリズム、HMACアルゴリズム、署名、対称性暗号化アルゴリズム、非対称性暗号化アルゴリズムです.暗号化アルゴリズムも可逆と不可逆に分けられています.例えば
md5
は非可逆暗号であり、暴力解読(衝突)しかできません.NodeJS開発においては、これらの暗号化アルゴリズムを直接使用しています.crypto
のハッシュ、HMAC、暗号解読、署名、検証機能を含む暗号化機能を提供しています.使用時にはインストール不要です.ハッシュ・アルゴリズム
ハッシュアルゴリズムは、任意の長さの入力を固定長の出力に変換するためのハッシュアルゴリズムとも呼ばれ、一般的には
OpenSSL
、md5
などがあり、これらのアルゴリズムは、元のデータに対する変換プロセスが暗号化と呼ばれることができるかどうかで論争されています.後で説明するために、まず暗号化と呼ばれます.//
const crypto = require("crypto");
// getHashes
console.log(crypto.getHashes());
// [ 'DSA', 'DSA-SHA', 'DSA-SHA1', 'DSA-cSHA1-old',
// 'RSA-MD4', 'RSA-MD5', 'RSA-MDC2', 'RSA-RIPEMD160',
// 'RSA-SHA', 'RSA-SHA1', 'RSA-SHA1-2', 'RSA-SHA224',
// 'RSA-SHA256', 'RSA-SHA384', 'RSA-SHA512',
// 'dsaEncryption', 'dsaWithSHA', 'dsaWithSHA1', 'dss1',
// 'ecdsa-with-SHA1', 'md4', 'md4WithRSAEncryption',
// 'md5', 'md5WithRSAEncryption', 'mdc2', 'mdc2WithRSA',
// 'ripemd', 'ripemd160', 'ripemd160WithRSA', 'rmd160',
// 'sha', 'sha1', 'sha1WithRSAEncryption', 'sha224',
// 'sha224WithRSAEncryption', 'sha256',
// 'sha256WithRSAEncryption', 'sha384',
// 'sha384WithRSAEncryption', 'sha512',
// 'sha512WithRSAEncryption', 'shaWithRSAEncryption',
// 'ssl2-md5', 'ssl3-md5', 'ssl3-sha1', 'whirlpool' ]
sha1
は開発においてよく使用されるアルゴリズムの一つであり、公式には要約アルゴリズムと呼ばれ、以下のいくつかの特徴がある.md5
によって暗号化されて戻ってきた結果は全く同じであるため、解読時には「衝突」によって暴力的に解読され、md5
によって暗号化されたmd5
によって連続して暗号化されたときには解読されにくいので、3
を使用して通常何度も暗号化される.// md5 —— Buffer
const crytpo = require("crytpo");
let md5 = crytpo.createHash("md5"); // md5
let md5Sum = md5.update("hello"); // update
let result = md5Sum.digest(); //
console.log(result); //
md5
メソッドパラメータは、暗号化された戻り値のフォーマットを指定するために使用され、デフォルトでは暗号化されたBufferに返されない.一般的なパラメータはdigest
とhex
、Base64
は16進数を表し、暗号化された長さはhex
、32
の結果長さはBase64
、24
で終了する.// md5 ——
const crypto = require("crypto");
let md5 = crypto.createHash("md5");
let md5Sum = md5.update("hello");
let result = md5Sum.digest("hex");
console.log(result); // 5d41402abc4b2a76b9719d911017c592
// md5 —— Base64
const crypto = require("crypto");
let md5 = crypto.createHash("md5");
let md5Sum = md5.update("hello");
let result = md5Sum.digest("Base64");
console.log(result); // XUFAKrxLKna5cZ2REBfFkg==
==
方法の戻り値はupdate
であり、現在の例であるので、チェーンコールをサポートし、長い情報を何回もthis
方法を呼び出してセグメント暗号化しても良いし、update
方法を呼び出しても同様に全体の暗号化された値に戻ります.//
const crypto = require("crypto");
let result = crypto
.createHash("md5")
.update("he")
.update("llo")
.digest("hex");
console.log(result); // 5d41402abc4b2a76b9719d911017c592
digest
を使用してセグメント化暗号化ができるので、ストリームと関連して使用することができ、実はupdate
の本質はcrypto
タイプの変換ストリームを作成することであり、読み取り可能なストリームを書き込み可能なストリームに変換することができる.// md5
const crypto = require("crypto");
let fs = require("fs");
let md5 = crypto.createHash("md5");
let rs = fs.createReadSteam("./readme.txt", {
highWaterMark: 3
});
//
rs.on("data", data => md5.update(data));
rs.on("end", () => {
let result = md5.digest("hex");
console.log(result);
});
使用シーン1:サーバとサーバの間で通信送信を行うなど、データのチェックによく使われます.ダイジェストにTransform
を加えて要約を暗号化した後の暗文は、受信側がデータを取得した後に、同じmd5
アルゴリズムで暗号化して暗号化された後、暗文ダイジェストと比較して検証されます.データ伝送中にハイジャックされたり、改竄されたりするのを防ぐためです.使用シーン2:ブラウザキャッシュポリシーでは、静的リソースに関する情報のダイジェストをmd5
を用いて暗号化し、暗号化された鍵をサーバに送信するたびに照合すればよく、ファイルの内容全体を比較することはない.短所:
md5
のハッシュアルゴリズムを使用して暗号化することが規定されているので、他の人は同じアルゴリズムを使って情報を偽造することができ、安全性は高くない.Hmacアルゴリズム
1、Hmacアルゴリズムの使用
Hmacアルゴリズムはまた塩添加アルゴリズムとも呼ばれ、署名の完全性の破壊を阻止するためにハッシュアルゴリズムを一つの鍵と結合し、
md5
暗号化のいくつかの特徴を備えている.//
const crytpo = require("crytpo");
let hmac = crytpo.createHmac("sha1", "panda");
let result = hmac.update("hello").digest("Base64");
console.log(result); // 7spMLxN8WJdcEtQ8Hm/LR9pUE3YsIGag9Dcai7lwioo=
md5
の最初のパラメータは、同じcrytpo.createHmac
であり、暗号化のアルゴリズムであり、一般的にはcrytpo.createHash
およびsha1
を使用しており、第2のパラメータは鍵である.sha256
方法で生成された暗号化結果の長さはdigest
より大きく、md5
で生成された結果の長さはhex
、64
で生成された結果の長さはBase64
であり、44
で終了する.セキュリティは
=
より高く、鍵によって暗号化されていますが、鍵が解読できないことが分かりません.欠点は鍵伝送のプロセスがハイジャックされやすく、いくつかのランダム鍵を生成することによって回避できます.2、鍵の作成方法
md5
クライアントをインストールし、コマンドラインを介して保存鍵のファイルを生成することができます.openssl genrsa-out rsa_prvate.key 1024
openSSH
は生成鍵を表し、openssl genrsa
は出力ファイルを表し、-out
はファイル名を表し、rsa_private.key
は出力鍵のサイズを表している.//
const fs = require("fs");
const crytpo = require("crytpo");
const path = require("path");
let key = fs.readFileSync(path.join(__dirname, "/rsa_private.key"));
let hmac = crytpo.createHmac("sha256", key);
let result = hmac.update("hello").digest("Base64");
console.log(result); // bmi2N+6kwgwt5b+U+zSgjL/NFs+GsUnZmcieqLKBy4M=
対称性の暗号化対称性暗号化は、データを送信する際に、鍵と暗号化アルゴリズムを用いて暗号化され、データを受信する際には同じ鍵と暗号化アルゴリズムの逆アルゴリズム(復号アルゴリズム)を用いて復号される必要があり、すなわち対称性暗号化のプロセスは可逆的であり、
1024
で使用されるアルゴリズムはcrytpo
である.//
const fs = require("fs");
const crypto = require("crypto");
const path = require("path");
let key = fs.readFileSync(path.join(__dirname, "/rsa_private.key"));
//
let cipher = crypto.createCipher("blowfish", key);
cipher.update("hello");
// final
let result = cipher.final("hex");
console.log(result); // 3eb9943113c7aa1e
//
let decipher = crypto.createDecipher("blowfish", key);
decipher.update(result, "hex");
let data = decipher.final("utf8");
console.log(data); // hello
暗号化はblowfish
方法を使用して、暗号解読はcrypto.createCipher
方法を使用するが、使用するアルゴリズムと鍵は同じでなければならない.crypto.createDecipher
のように、暗号化時のフォーマットを第2のパラメータで指定しなければならない.対称性の暗号化を使用する文字列は長さ制限があり、
update
文字を超えてはいけません.そうでないと暗号化に成功しますが、復号できません.短所:鍵は伝送中に入手しやすく、安全リスクがある.
非対称暗号化
非対称暗号化相も可逆的であり、対称性よりも安全であり、メッセージ送信者と受信者はローカルで鍵のペアを作成し、公開鍵と秘密鍵を互いに相手に送信し、メッセージ送信時には相手の公開鍵を使って暗号化し、相手がメッセージを受信した後に彼の秘密鍵を使って解読する.このように、公開鍵の配信中に切断されても解読できない.公開鍵の暗号化されたメッセージは、ペアの秘密鍵のみが復号されるからである.
次に、
hex
を使用して、以前に生成された秘密鍵final
に対して、対応する公開鍵を生成し、以下のように命令する.openssl rsa-in rsa_prvate.key-pubout-out rsa_public.key
上記のコマンドは、1つの秘密鍵から対応する公開鍵を生成し、
utf8
は公開鍵出力を表し、7
は公開鍵のファイル名である.//
const fs = require("fs");
const crypto = require("crypto");
const path = require("path");
//
let publicKey = fs.readFileSync(path.join(__dirname, "/rsa_public.key"));
let privateKey = fs.readFileSync(path.join(__dirname, "/rsa_private.key"));
//
let secret = crytpo.publicEncrypt(publicKey, Buffer.from("hello"));
//
let result = crytpo.provateDecrypt(privateKey, secret);
console.log(result); // hello
公開鍵を用いて暗号化する方法はopenSSH
であり、第一のパラメータは公開鍵であり、第二のパラメータは暗号化情報であり、秘密鍵を用いて復号する方法はrsa_private.key
であり、第一のパラメータは秘密鍵であり、第二のパラメータは復号情報である.署名する
署名は非対称性暗号と非常に類似しており、公開鍵と秘密鍵とは異なり、相手は公開鍵を用いて暗号解読検証を行い、このデータが秘密鍵の所有者から送信された元のデータであることを保証し、ネットワーク内の伝送過程では変更されていない.
また、以下のように署名コードを実装するために
-pubout -out
およびrsa_public.key
を公開鍵および秘密鍵としても使用する.//
const fs = require("fs");
const crypto = require("crypto");
const path = require("path");
//
let publicKey = fs.readFileSync(path.join(__dirname, "rsa_public.key"), "ascii");
let privateKey = fs.readFileSync(path.join(__dirname, "rsa_private.key"), "ascii");
//
let sign = crypto.createSign("RSA-SHA256");
sign.update("panda");
let signed = sign.sign(privateKey, "hex");
//
let verify = crypto.createVerify("RSA-SHA256");
verify.update("panda");
let verifyResult = verify.verify(publicKey, signed, "hex");
console.log(verifyResult); // true
署名を生成するcrytpo.publicEncrypt
方法には2つのパラメータがあり、第1のパラメータは秘密鍵であり、第2のパラメータは署名を生成するフォーマットであり、最後に返したcrytpo.provateDecrypt
は生成した署名(文字列)である.署名を検証する
rsa_public.key
方法には、3つのパラメータがあり、1つ目のパラメータは公開鍵であり、2番目のパラメータは検証された署名であり、3番目のパラメータは署名を生成するときのフォーマットであり、ブール値に戻ります.すなわち、検証されたかどうかです.使用シーン:cookie署名をブラウザに返すためによく使われています.ブラウザがドメインサーバにアクセスしてクッキーを持ってきたら検証します.クッキーが改竄されるのを防ぎ、CSRFスパンが偽造を要求します.
締め括りをつける
様々な項目は、データ伝送時に情報の感度と用途に応じて異なる暗号化アルゴリズムと暗号化方式を行い、NodeJSにおいて
rsa_private.key
のAPIは、完全に私たちの暗号化ニーズを実現することができ、上の暗号化スキームを組み合わせて使用して、より複雑な暗号化スキームを実現することもできる.