いよいよ開幕、jigインターン2021夏、昨年に続きコロナ仕様でオンライン。同時最多の20名!
お楽しみjigBOXの開封後、恒例のメガネ堅パン記念写真。
盛り上がったオンラインアイスブレイクの新企画、チーム毎に分かれての家のモノでつなげるしりとりチャレンジ。制限時間5分。Dチームが15コで優勝!
テーマ別ブレイクアウトルームと合わせたランチタイムの後は、勉強会!
「JavaScript (Deno) でつくる超かんたんwebアプリ入門」
2時間枠、Denoのインストール、JavaScriptを使ったサーバーサイドプログラム、ブラウザで動くフロントエンドプログラムの基本をざっとハンズオンで伝授。全員動きました!
つまづき勝ちな環境構築。Denoのインストールした後、「deno」コマンドで動かない時は。環境変数のPATH(パス)を設定します。
Windowsの場合、PowerShell(VSCodeのTerminal、または、ファイル名を指定して実行 powershell)で、下記コマンドの「fukuno」を自分のコンピューターでのユーザー名に変更して実行
$ENV:Path="/Users/fukuno/.deno/bin/;"+$ENV:Path
Macの場合はこちら(同じく「fukuno」を自分のユーザー名に変更)
echo "export DENO_INSTALL="/Users/fukuno/.deno"" >> ~/.zshrc
echo "export PATH="\$DENO_INSTALL/bin:\$PATH"" >> ~/.zshrc
チーム開発とスクラム、ファイル管理のGitHubに関して基本を押さえ、アイデア出しからのチーム開発開始!
各チーム、アイデアが出揃ったところで、プロダクトバックログ(優先順位付きの作るものリスト)を作って、タスクに分割。具体的な技術的な質問が出始めました。
円滑なチーム開発に必須な、プログラムのファイル分割。JavaScriptではこのようにします。
例として、パラメータを2つとって足し算する関数 add を含む、ファイル add.js を作ります。
const add = (param1, param2) => {
return param1 + param2;
};
関数addを他のファイルから呼び出せるようにするために export を追加します
export { add };
試しに呼び出してみる test.js を作ってみます。(ローカルなファイルは ./ で始める必要あり)
import { add } from "./add.js";
console.log(add(1, 2));
動かす時は deno run
$ deno run test.js
複数の関数をexport/importしたい場合は、export { add, sub, mul } と増やせばok。必要なものだけimportすればいいので、import { add, sub } と書けます。
import/exportを使ったJavaScriptのプログラムをESモジュールと呼びます。
一見大きな課題も、分割して、分担して、それぞれ作って組み合わせたら、自分ひとりではなし得ないモノができますよ!
「E2EEメッセージングヘルパー」src on GitHub
PureなESモジュールによるE2EE実装。ECDHを使った鍵共有から、もう一歩進めてAES-GCMによる暗号化復号化にも対応。
AES-GCM-esのプログラムから、ForgeをforkしてESモジュール化したforge-esをimportしている様子などチェックしてみましょう。
こちら、キーペア生成、相手の公開鍵を受け取った鍵共有、暗号化、復号化の実装です。
generatebutton.onclick = async () => {
const keypair = ECDH.generateKeys(curve);
ecdhpublickey.value = keypair.publicKey.buffer.toString("hex");
ecdhprivatekey.value = keypair.privateKey.buffer.toString("hex");
};
generatebutton2.onclick = async () => {
const privateKey = ECDH.PrivateKey.fromBuffer(curve, Buffer.from(ecdhprivatekey.value, "hex"));
const peerPublicKey = ECDH.PublicKey.fromBuffer(curve, Buffer.from(ecdhpublickey2.value, "hex"));
const secretKey = privateKey.deriveSharedSecret(peerPublicKey);
ecdhsecretkey.value = hex.fromBin(secretKey);
iv = AESGCM.createIV();
};
encryptbutton.onclick = async () => {
const data = new TextEncoder().encode(ecdhmessage.value);
const key = hex.toBin(ecdhsecretkey.value);
AESGCM.incrementIV(iv);
const [encdata, tag] = AESGCM.encrypt(key, iv, data);
ecdhciphertext.value = hex.fromBin(iv) + "_" + hex.fromBin(encdata) + "_" + hex.fromBin(tag);
};
decryptbutton.onclick = async () => {
const key = hex.toBin(ecdhsecretkey.value);
const [iv, encdata, tag] = ecdhciphertext.value.split("_").map(h => hex.toBin(h));
const data = AESGCM.decrypt(key, iv, encdata, tag);
if (data) {
ecdhmessage.value = new TextDecoder().decode(data);
} else {
ecdhmessage.value = "復号失敗";
}
};
共通鍵を使った安全な暗号化と言われるAES-GCMですが、鍵と合わせて使用するIV(初期化ベクトル)の使い方を間違うと第三者が復号できてしまいます。
上記ではIVはランダムに生成し、暗号化のたびにインクリメントする形で実装しています。
(参考、本当は怖いAES-GCMの話 - ぼちぼち日記)
情報セキュリティに興味が出てきたら、中高生のためのサイバーセキュリティコンテスト「CyberSakura / サイバーサクラ」への参加、応援もご検討ください!
jigインターンによるレポート「⭐jigintern diary⭐」もスタート。各チーム、交代で毎日1名ずつアップ、最終日には全員による統括ふりかえりが公開されます。
お楽しみに!