iEhohs.com

ウェブ&システム担当の仕事メモ的なブログ。個人的な記事ばかりです。

『週刊アスキー』「JavaScriptの部屋 第33回 暗号化の基礎:換字暗号で秘密の手紙を送る!」学習メモ

学習メモ

新型コロナウイルスの流行によって、これまでテレワークと縁遠かった業界や職種であっても導入せざるを得なくなってきました。

テレワークで怖いのは個人情報の流出。これまで以上に情報をメールなどの通信で受送信するわけですから、間違った相手に送ってしまいがちです。

情報自体を暗号化できる方法はないかと考えていたところ、週刊アスキーのコーナーである「JavaScriptの部屋」で過去に文章を暗号化させる方法が紹介されていたことを思い出しました。

https://ascii.jp/asciiclub/

アスキーの会員になってバックナンバーを辿ったところ、ドンピシャなものが見つかりました。そういうわけで紹介されていたソースを写経して作りました。

サンプルページ

https://www.iehohs.com/ftp/cipher.html

僕は任意の文字列を付してハッシュ化する方法を探していましたが、紹介されていたのはまた別の方法。

文章の1文字ずつUTF-16の文字コードに変換して数値化し、さらに暗号鍵の1文字も同様に変換して足し算し、元の文字コードに戻します。1文字進むごとに暗号鍵も1文字進んでいきます。

復元する時は逆のことをするだけ。UTF-16に変換して、暗号鍵の分数値を引いて元の文字コードに変換すれば、暗号化前の文字に戻ります。

さらに僕なりのアレンジということで、変換後のテキストをクリップボードにコピーするボタンを設置。

できれば変換前のテキストにクリップボードからペーストもやりたかったのですが、いまいちやり方がわからなかったので今回はパス。

あと文字コードのデフォルトをUTF-8にしました。

HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>暗号作成</title>
<script>
var textFile;           // テキストファイル

function init() {
    // ボタンの無効化
    document.getElementById("cipher").disabled = true;
    document.getElementById("decipher").disabled = true;
}

function loadText(e) {
    // テキストファイルの取得
    textFile = e.files[0];
    
    // テキストデータの読み込み
    readText();
}
    
function readText() {
    var reader = new FileReader();
    
    // 読み込み完了後の処理
    reader.onload = function() {
        // テキストデータを変換前テキストエリアにセット
        document.getElementById("source").value = reader.result;
    };
    
    // 選択された文字コードを取得
    var encList = document.getElementById("encList");
    var encoding = encList.options[encList.selectedIndex].value;
    
    // テキストファイルとして読み込み実行
    reader.readAsText(textFile, encoding);
}
    
function checkKey() {
    // 暗号鍵が入力されていればボタンを有効化
    if (document.getElementById("key").value != "") {
        // ボタンの有効化
        document.getElementById("cipher").disabled = false;
        document.getElementById("decipher").disabled = false;
    } else {
        // ボタンの無効化
        document.getElementById("cipher").disabled = true;
        document.getElementById("decipher").disabled = true;
    }
}

function cipher(n) {
    // 変換前、暗号鍵の取得
    var source = document.getElementById("source").value;
    var key = document.getElementById("key").value;
    
    // n=1:暗号化、n=2:復元
    var code, keyCode;
    var keyIndex = 0
    var destination = "";
    for (var i=0; i<source.length; i++) {
        // UTF-16 コードに変換
        code = source.charCodeAt(i);
        // コードに暗号鍵を追加/削除して文字に戻す
        keyCode = key.charCodeAt(keyIndex);
        if (n == 1) {
            destination += String.fromCharCode(code+keyCode);
        } else {
            destination += String.fromCharCode(code-keyCode);
        }
        // 次の暗号鍵へ
        keyIndex++;
        if (keyIndex == key.length) keyIndex = 0;
    }
    document.getElementById("destination").value = destination;
}
    
function saveText() {
    // テキストをBLOBに変換
    var destination = document.getElementById("destination").value;
    var blob = new Blob([destination], {type:"text/plain"});
    
    // 名前をつけて保存(ダウンロード)
    var filename = window.prompt("ファイル名を入力してください",
     "cipher.txt");
    if (filename != null) {
        if (window.navigator.msSaveBlob) {
            // msToBlobを使用できるブラウザー
            window.navigator.msSaveBlob(blob,filename);
        } else {
            var a = document.createElement('a');
            a.href = URL.createObjectURL(blob);
            a.download = filename;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
        }
    }
}

function copyClipBoad() {
    // 変換後のテキストをクリップボードにコピー
    var copyText = document.getElementById("destination");
    copyText.select();
    document.execCommand("copy");
}
</script>
</head>
<body onload="init()">
<p>暗号作成</p>
<input id="file" type="file" accept="text/plain" onchange="loadText(this)">
文字コード:
<select id="encList" onchange="readText()">
<option value="utf-8">UTF-8
<option value="shift-jis">Shift-JIS
</select>
<hr />
変換前:<br />
<textarea id="source" cols="80" rows="10"></textarea>
<br />
暗号鍵:<input type="password" id="key" oninput="checkKey()">
<input type="button" id="cipher" value="暗号化" onclick="cipher(1)">
<input type="button" id="decipher" value="復元" onclick="cipher(2)">
<hr />
変換後:<br />
<textarea id="destination" cols="80" rows="10"></textarea>
<br />
<input type="button" name="Copy" value="コピー" onClick="copyClipBoad()">
<input type="button" value="保存" onclick="saveText()">
</body>
</html>

そのまんま写しちゃいましたが結構昔のなのでお許しを〜。

プログラムは写経するだけでも勉強になるとはいいますが、確かにその通りですね。

「これどういう意味なんだろ?」ってところがまだ消化できていないので、まずはそこから。

週刊アスキーのこのコーナーはとてもおもしろいので、今後も良さげなのがあったら写経しましょ。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です