LoginSignup
32
21

More than 3 years have passed since last update.

Node.jsで文字列を暗号化・復号する 【string encryption in node.js】

Last updated at Posted at 2019-05-30

どれだけニーズがあるのかわからないが、データベースに入ってるidとかを必要な時に難読化したかった。

例えば、example.com/1/profileみたいなURLだと、「1のところを2に変えたら他の人のプロフィール見えるんじゃないの」みたいなのをトライできないようにしたい。

で、とりあえずstringを入力したらそいつをencryptした文字列を返却するモジュールを作ってみよう。
加えて、Adminの立場的にはencryptされた文字列を見るのはめんどくさいのでdecryptもできるようにしよう。

nodeにはcryptoという暗号化周りの組み込みモジュールが存在するので、そいつを利用する。

ドキュメント: https://nodejs.org/api/crypto.html

const crypto = require('crypto');

const ENCRYPTION_KEY = "HH95XH7sYAbznRBJSUE9W8RQxzQIGSpy" // 32Byte. このまま利用しないこと!
const BUFFER_KEY = "RfHBdAR5RJHqp5wm" // 16Byte. このまま利用しないこと!
const ENCRYPT_METHOD = "aes-256-cbc" // 暗号化方式
const ENCODING = "hex" // 暗号化時のencoding

const raw = JSON.stringify({userId: 1}) // 暗号化する対象。stringなら何でも。

function getEncryptedString(raw) {
  let iv = Buffer.from(BUFFER_KEY)
  let cipher = crypto.createCipheriv(ENCRYPT_METHOD, Buffer.from(ENCRYPTION_KEY), iv)
  let encrypted = cipher.update(raw)

  encrypted = Buffer.concat([encrypted, cipher.final()])

  return encrypted.toString(ENCODING)
}

function getDecryptedString(encrypted) {
  let iv = Buffer.from(BUFFER_KEY)
  let encryptedText = Buffer.from(encrypted, ENCODING)
  let decipher = crypto.createDecipheriv(ENCRYPT_METHOD, Buffer.from(ENCRYPTION_KEY), iv)
  let decrypted = decipher.update(encryptedText)

  decrypted = Buffer.concat([decrypted, decipher.final()])

  return decrypted.toString()
}

// 以下は試してみてるだけ

console.log(`raw: ${raw}`)

const encrypted = getEncryptedString(raw)

console.log(`encrypted: ${encrypted}`)

const decrypted = getDecryptedString(encrypted)

console.log(`decrypted: ${decrypted}`)

上記をコピペして適当なファイル名(encryption-sample.js とか)をつけて、node encryption-sample.jsを叩くと下記のようなアウトプットになるはず

raw: {"userId":1}
encrypted: e3629d8ff7295f693569359d06fd4da2
decrypted: {"userId":1}

今回は、getEncryptedString()に対してあるstring: Aを渡した場合に、どんな場合でも同じ結果string: A'が返ってきてほしかったので、let iv = Buffer.from(BUFFER_KEY)の部分で必ず同じiv (= initialization vector)が生成されるようにしています。

ただし、用途によっては毎回異なるivを生成し、encryption結果が毎回変わることが正な場合もある(というか本来の目的ではそちらのほうが正?)ので気をつけて下さい。

それについては上記のコードが参考になると思います。
というか僕が参考にしました。

32
21
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
21