鍵生成、交換、暗号化を自前で実装してチャットシステムを作った話(コード付き)
こんにちは、大学院生のYukiです。
そろそろ期末テストの時期になってきました。
前期までは難易度の低い科目ばかりで高い評価を獲得できていましたが、現在のセメスターは総じて難易度が飛び抜けた科目しか残っておらず、大惨事の予感が拭えません。先輩方から伺った落単率の高さに戦々恐々としており、学習の手を抜くことができません。
さて、本日は授業や研究の息抜きとして、セキュアな通信を実現するTCPレベルのAES(RSA)暗号化とDH鍵交換を使用したチャットアプリケーションを作成したお話です。
安全なシステム設計は一種開発においての定石になっているので、ほとんどのエンジニアはこれらのセキュリティ技法はあまり意識していないと思います。基本や応用情報学習者、Authや3rd決済関係のAPIを扱ったことがあれば概念の理解はあるはず。
インフラやIaaSの設計、スマートコントラクトの実装を経験したエンジニアは、必然的に設計書を書く機会が多くあります。そのため、個々の技術用語に詳しくなくても、セキュアなシステム構造の全体像は把握できているかもしれませんね。
今回は「概念だけ理解したエンジニア」の枠組みから脱却して実際に使用するイメージを持つために、あるチャットシステムを作成しました。
最初は大学院の講義で習った鍵交換の概念をターミナルで簡易実装しただけでしたが、
tkinterを使用した3者間P2P→n人対応P2P→n人対応Client-server→Djangoでフロントを作り直して結合して公開するに至りました。
始まりからそもそもTCPレベルだったので全て低レベル層からスクラッチ実装しています。
Djangoで稼働確認をする際に幾重にもトラブルがあり、改めてHTTPサーバーやWebSocketなどの既存ライブラリの偉大さを実感しました。「ここは楕円曲線、ここはRSAで絶対に暗号化したい」などのこだわりがなければ通常のアプリ開発者は使用する機会はないと思います。サービスの公開を見据えて技術選定している段階なら、まずは推奨されるメジャーな方法で完成させた方が絶対にコスパがいい。
サービスプロバイダーの目線からすると、カスタムソケットでオンライン対戦などを最適化したい、アルゴリズムを自身で比較選択して少しでも低レイテンシー耐障害性を叶えたいなど、
特定のサービスに対し開発スピード度外視でパフォーマンス性能を上げる際の選択肢として検討する余地がありそうです。
設計も書かずにゴリゴリコードを書いたので非常にメシーですが、
個人的にはBackendはどこに何があるか把握できていて、「次作るときはこういうフォルダ分けして、この機能はひとまとめにできるなぁ」と設計するにあたり問題ないレベルの理解にまで落とし込めたので満足しています。
上記が気になる文字よりもコード読む方が理解が早い方々は、サクッと実行してcypher textを出力しながらシーケンス図を書いてみるのをお勧めします。
テスト10日前なので雑談は程々に。
次回は11月半ばより投稿を再開できればと思います。
Yuki