JScriptで暗号化、復号化


## はじめに

以前、「[JScriptでHash取得](http://qiita.com/tnakagawa/items/9bcc26b501f5b995d896)」の時に「System.Security.Cryptography.SymmetricAlgorithm」系の
対称アルゴリズムがあったので、暗号化、復号化をやってみました。

## 暗号化、復号化

対称アルゴリズムは、「Rijndael」
共有キーは、パスワード文字列を「SHA256」でハッシュした値
初期化ベクターは、パスワード文字列を「MD5」でハッシュした値
としています。
（共有キーと初期ベクターのサイズにあっている為）

「byte配列」の長さを取得する方法がカッコ悪いです。
どなたか、他の方法を知っていたら教えてください。

```js
// 「byte配列」暗号化
function encrypt(pass, srcBytes) {
    return crypt(true, pass, srcBytes);
}

// 「byte配列」復号化
function decrypt(pass, srcBytes) {
    return crypt(false, pass, srcBytes);
}

// 変換メソッド
function crypt(enc, pass, srcBytes) {
    // 変換後byte配列
    var destBytes = null;
    // 暗号、複合、アルゴリズム生成
    var crypt = new ActiveXObject("System.Security.Cryptography.RijndaelManaged");
    // 「System.Text.UTF8Encoding」生成
    var encorde = new ActiveXObject("System.Text.UTF8Encoding");
    // パスワード文字列をbyte配列化
    var passBytes = encorde.GetBytes_4(pass);
    // 共有キー用ハッシュアルゴリズム生成
    var keyHash = new ActiveXObject("System.Security.Cryptography.SHA256Managed");
    // 共有キー用パスワードのハッシュ生成
    keyHash.ComputeHash_2(passBytes);
    // 共有キー設定
    crypt.Key = keyHash.Hash;
    // 後処理
    keyHash.Clear();
    // 初期化ベクター用ハッシュアルゴリズム生成
    var ivHash = new ActiveXObject("System.Security.Cryptography.MD5CryptoServiceProvider");
    // 初期化ベクター用パスワードのハッシュ生成
    ivHash.ComputeHash_2(passBytes);
    // 初期化ベクター用設定
    crypt.IV = ivHash.Hash;
    // 後処理
    ivHash.Clear();
    // 変換オブジェクト
    var transform = null;
    // 暗号化判定
    if (enc) {
        // 暗号化オブジェクト取得
        transform = crypt.CreateEncryptor();
    } else {
        // 復号化化オブジェクト取得
        transform = crypt.CreateDecryptor();
    }
    // データサイズ取得
    var len = getBytesLength(srcBytes);
    // データ変換
    destBytes = transform.TransformFinalBlock(srcBytes, 0, len);
    // 後処理
    crypt.Clear();
    // 変換後byte配列
    return destBytes;
}

// 「byte配列」の配列長取得
function getBytesLength(bytes) {
    var len = 0;
    // 「DOMDocument」生成
    var doc = new ActiveXObject("Msxml2.DOMDocument");
    // 「DomNode」生成（hex）
    var element = doc.createElement("hex");
    // 「dataType」に「bin.hex」を設定
    element.dataType = "bin.hex";
    // 「nodeTypedValue」に「byte配列」を設定
    element.nodeTypedValue = bytes;
    // 「text」を取得、配列計算
    len = element.text.length / 2;
    // 後処理
    element = null;
    doc = null;
    return len;
}
```

## 例

「[JScriptでHash取得](http://qiita.com/tnakagawa/items/9bcc26b501f5b995d896)」や「[JScriptでBase64](http://qiita.com/tnakagawa/items/beaec98fd64b20894245)」で作成したメソッドを利用します。


```js
// 暗号化対称文字列
var string = "あいうえお";
WScript.Echo("BEFORE :" + string);
// byte配列化
var srcBytes = string2bytes(string);
WScript.Echo("BYTES  :" + bytes2base64(srcBytes));
// 暗号化
var encBytes = encrypt("pass", srcBytes);
WScript.Echo("ENCRYPT:" + bytes2base64(encBytes));
// 復号化
var decBytes = decrypt("pass", encBytes);
WScript.Echo("DECRYPT:" + bytes2base64(decBytes));
// 複合化されたbyte配列を文字列化
WScript.Echo("AFTER  :" + bytes2string(decBytes));
```

結果は以下のとおりです。

```
BEFORE :あいうえお
BYTES  :44GC44GE44GG44GI44GK
ENCRYPT:vc2Lxfey98qvmwNh9Ut5qg==
DECRYPT:44GC44GE44GG44GI44GK
AFTER  :あいうえお
```

JSON型の文字列を暗号化してからファイルに保存して、使う時に復号化するって時などに使えるかもしれません。
（パスワード等が入っているファイルをそのまま置かないで済む・・・まあ、コードみたらバレバレだけど）