9
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

crypticoでPure JavaScriptによる公開鍵暗号を用いるメモ

Last updated at Posted at 2018-10-13

ブラウザ上で公開鍵を用いて暗号化してから送信、そのままDBに保存、サーバー側で参照するときに復号というシチュエーションで使えるJavaScriptのライブラリを調査しました。

メモとして手順や注意点を残します。

cryptico

クライアントとサーバーの両方で使えるライブラリとなると、このcryptico以外見つけられませんでした。
最後の更新が6年前となかなかの枯れ具合です。

NPM版がこちらで、構成が少し違っています。

オリジナルの方は、秘密鍵の永続化の手段がありませんでしたが、NPM版にはその手段が補われています。

キーの生成

OpenSSH形式を使えたらよかったのですが、秘密鍵を独自のJSON形式で永続化するのが楽でした。

gen.js
const Cryptico = require('cryptico'),
  Fs = require('fs');

// ビット数とパスフレーズ
const bits = 2048;
const passphrase = 'the-passphrase';

// キーの生成
console.log('generating...');
const key = Cryptico.generateRSAKey(passphrase, bits);

// 公開鍵の保存
Fs.writeFileSync('./public.key', Cryptico.publicKeyString(key));

// 秘密鍵の保存
Fs.writeFileSync('./private.json', JSON.stringify(key.toJSON()));
console.log('complete');

秘密鍵はいわばパスフレーズ込みの状態で永続化されるようで、この後パスフレーズを使うことはありませんw

暗号化

Node.js向けのプログラムですが、公開鍵をテキストで用意してあげて、crypt.cipherを参照すれば暗号文を取得できます。この部分はブラウザでも容易に実行可能です。

miyanagaという平文を暗号化します。

encrypt.js
const Cryptico = require('cryptico'),
  Fs = require('fs');

// 公開鍵
const key = Fs.readFileSync('./public.key').toString();

// 平文
const plain = 'miyanag';

// 暗号化
const crypt = Cryptico.encrypt(plain, key);

// 暗号文
Fs.writeFileSync('./cipher.txt', crypt.cipher);
console.log(crypt.cipher);

このような暗号文が取得できました。

UbV1xXLUzISZBUF9ZkqwBPXtYbueCTeLfxVuNcQldlgz304vHddZjcBX2df/D2t2dANVyZPgDLugAablFy5YMhepwlDS+i1blJ8OPKOCSN7WSP8k3uRc0XKgeISvzayynbgwmv0rR8dXtI752hJk/mXnY8dcYhQqlgDkjs1nWbXrRl4py5Te1qxGs+kpHHWr7ySYsnBmRkkW1WErgB8peh5EH2/bhLH/OzVh6yoUrghS57ErtLz/OoIZCwLiTHU2JU6t5fnSoqxIKwnpX+ET8YWdDn4R4sepC176X5OmYF+hUD7QXDijT4GaZfKhvQ0zt8AUyGtvHboGnz5xKLtQGg==?AtqooM9ANbOhW/XxANySb+Sp2uwiUIonJx3qsTouZRw=

復号

RSAKey.parseで秘密鍵を復元できます。

decrypt.js
const Cryptico = require('cryptico'),
  Fs = require('fs');

// JSON形式の秘密鍵を復元
const keyJson = Fs.readFileSync('./private.json').toString();
const key = Cryptico.RSAKey.parse(keyJson);

// 暗号文
const cipher = Fs.readFileSync('./cipher.txt').toString();

// 復号
const decrypt = Cryptico.decrypt(cipher, key);

// 平文
console.log(decrypt.plaintext);

無事、平文miyanagaを取得できました。
ライブラリの古さは感じましたが、容易に目的は達成できました。

9
10
0

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?