node.jsを使って、暗号化ファイルをビルドする為のメモ。
一括変換ツールを作る時等は、sync系が扱いやすい。
nodeはバージョンによって機能があったりなかったりするので、
環境確認が面倒だけど、環境を選ばないのが素敵。
参照
https://nodejs.org/api/crypto.html
動作確認環境
- macOS 10.12.3
- npm -v 3.10.9
- node -v v7.2.0
ファイルを暗号化
function cipher(data, algorithm, password){
var crypto = require("crypto");
var cipher = crypto.createCipher(algorithm, password);
return Buffer.concat([cipher.update(data), cipher.final()]);
}
var fs = require('fs');
var inData = fs.readFileSync(filepath);
var cipheredData = cipher(inData, 'aes-256-cbc', 'password');
fs.writeFileSync(filepath, cipheredData);
algorithmは、aes-256-cbcやaes-256-ctr等たくさんあるが、
使用可能な一覧の確認は、以下で可能
console.log( crypto.getCiphers() );
改ざん検出用にHMACを入れてみる
function hmac(data, algorithm, password){
var crypto = require("crypto");
var hmac = crypto.createHmac(algorithm, password);
hmac.update(data);
return hmac.digest();
}
var fs = require('fs');
var inData = fs.readFileSync(filepath);
var hmacData = hmac(inData, 'sha256', 'password');
// ファイルデータの先頭にHMACを挿入
inData = Buffer.concat([hmacData, inData]);
// HMACを含めたファイルデータをまとめて暗号化
var cipheredData = cipher(inData, 'aes-256-cbc', 'password');
fs.writeFileSync(filepath, cipheredData);
HMACの挿入は先頭でも末尾でも都合の良い方で問題無いと思う。
ハッシュ関数の選択によりHMACのサイズが変わるが、
今回はsha256にしてみたのでサイズは 256bit = 32byte
改ざん検出をする場合は、使用側で33バイト目からのデータでHMACを作って
1 - 32バイトのデータと比較すれば良い。
圧縮してみる
データサイズも気にしないとね。
zlib.deflateSync が便利。
var fs = require('fs');
var inData = fs.readFileSync(filepath);
var zlib = require('zlib');
var deflatedData = zlib.deflateSync(inData);
先に圧縮してから暗号化した方がデータサイズが小さくなりやすいみたいだけど、
暗号強度下がるかな。。。
LUAのコンパイルしてみる
ついでなので。
https://www.npmjs.com/package/luac
var luac = require('luac');
luac.buildToFileSync(filepath, outFilePath);
組み合わせてみる
改ざん検出用ハッシュ付き暗号化圧縮コンパイル済みluaデータファイルの作成
var luac = require('luac');
luac.buildToFileSync(filepath, filepath);
var fs = require('fs');
var data = fs.readFileSync(filepath);
// 圧縮データにする
var zlib = require('zlib');
data = zlib.deflateSync(data);
// ファイルデータの先頭にHMACを挿入
var hmacData = hmac(data, 'sha256', 'password');
data = Buffer.concat([hmacData, data]);
// HMACを含めた圧縮ファイルデータをまとめて暗号化
data = cipher(data, 'aes-256-cbc', 'password');
fs.writeFileSync(filepath, data);