怠惰の極み

怠惰な学生かもしれない

セキュリティ・キャンプの応募課題を晒す会

本文の内容の正確性は知りません。課題を晒すということで、そのままです。

セキュリティ・キャンプとはなんぞや

22歳以下の学生が参加できるIPAによる人材の育成発掘事業です。本来は合宿形式で行われていますが、2年前からはオンラインでの長期開催になっていて、今年度もオンライン開催のようです。 オフラインも良さそうだけど、オンラインもオンラインでいい所もありそう。

www.ipa.go.jp

応募したトラックについて

去年(2021年)セキュリティ・キャンプ全国大会2021にありがたく参加させていただいたので、その応募課題を晒そうと思います。今年も応募始まったみたいだし。中学生っていういいご身分だったもんで、ジュニア開発ゼミ(中学生以下のみ参加可)とAの帰ってきたフィジカルトラックの両方に応募しました。応募する時にどっちを優先するか、みたいなものを選ぶ欄があったと思います。最終的にAの帰ってきたフィジカルトラックに受かりました。両方晒しますが、ジュニア開発ゼミに受かったのかはわからないのです。

やつ

やつです。本文。まず最初にAトラックの方から。

問1 本コースが求める人物像を以下の通りです。それらをアピールできるエピソードを書いてください。 ・ 低レイヤーに興味があり実際に手を動かして現象を確かめてみないと気が済まない ・ 自分が得た知見をより多くの人たちと共有しようとする ・ 技術支援コミュニティの主宰、運営、参加等の経験

思いっきりプライベートのこと書いちゃったので本文は晒せませんが、中学校の部(ロボットを作ったりする部です。)の経験を中心に書きました。

問2 あなたの技能を推し量る問題を設問し、それに自分で回答してください。あなたの得意分野の技量がわかるものであれば自由に設問して頂いて結構です。

Q ライントレースロボットについて語ってくれますよね???????(圧) A はい……………(←圧力に屈した人の図)

そもそもライントレースとは何なのか。 それはラインをトレースすることである。では、ラインとは何なのか。ラインとは線のことである。この場合、黒か白の線を使う。では、トレースとは何なのか。トレースとは追従である。すなわち、ライントレースとは線を追従することである。ライントレースをするロボットのことをライントレーサーという。つまり、ライントレース競技とはフィールドに引かれた線を追従し、ゴールに到達するまでの時間を競う競技である。勿論、タイムが早いほうが上位となる。

ロボトレース競技 ライントレース競技として有名な大会にマイクロマウスのロボトレース競技がある。1周60m以下のコースを3分間で3回まで走行できる。同じコースを3回走る。1回目でルートを記憶し、2回目・3回目では直線の時は加速、曲線が近づいたら減速をするなどのコースに合わせた走行が求められる。

黒に白か、白に黒か 正直どっちでもいい、マジでどっちでもいい。そんなに速く走らない限りは。 黒字に白いラインは、環境条件に左右されにくいことというメリットがある。コースから外乱光が反射しにくく、センサが誤反応を起こしにくい。これによってより高速域での走行が可能になる。マイクロマウスのロボトレース競技などではこちらが用いられる。白地に黒のメリットはやはりその入手性の良さである 百均に売られているプラダンでコースを作れる。安い。ほら、そこの君!運ぶの面倒とか言わない!!というかほとんどのライントレースコースって白地に黒じゃね???ほとんどの場合において、コースに黒と白以外の色は使われない。

競技の説明はこれぐらいにしておいて、そろそろ真面目にハードウェアの話でもしますかね?

モーター 大きく分けて二種類のモーターが使われる。ステッピングモーターとDCモーターだ。ステッピングモーターはモータードライバに送る信号によって、回る角度を指定できる。これによって、かなり正確にロボットの自己位置を割り出すことや正確にロボットの位置制御ができる。DCモーターは電池をつなげばそのまま回るモーターだ。小学校の理科で作った記憶がなくもない。DCモーターの利点は回転が早いこととモーター自体が軽量であることだ。これによって、ロボットの大幅な高速化が見込まれる。ただ、DCモーターはエンコーダなしには、回転数を正確に制御することができない。

センサー ラインがどこにあるかを見つけるために、センサーを用いる。色によって光を吸収するか反射するかの違いから、センサーの示す値を読みとってラインと自身の位置関係を把握する。主に赤外線センサーが用いられる。要は人間の目。たまに画像認識とかする頭おかしい人がいるけど気にしてはいけない。絶対にね。

モータードライバ 要はモーターのドライバだ。これに信号を送ることによってモーターを制御する。DCモータードライバでは主に入力パルスのDuty比によって速度が変わり、入力するピンによって回転する方向が変わる。それに対してステッピングモータードライバは様々な種類があり制御方法は多種多様である。I2Cを使ったものや1パルスの入力で1ステップ動くもの、DCモータードライバを2つくっつけたようなものまである。

マイコン マイコンというのは人間でいう脳だ。マイコンの役割は、プログラムされた通りにセンサーなどからの入力に基づいていろいろな物を制御することだ。この場合はセンサーの値を読み取ってモータードライバに指示をする。ライントレースに適するマイコンとしてPIC,Arduino,STM32などがある。Arduinoは買ってすぐに使える上、プログラムコードが単純なので初心者に向いている。PICは様々な種類があり、用途に合わせてマイコンを選択できるが、半導体そのものとして売られているのでマイコンボードのような物を作らないとならない。STM32は様々な種類が売られている。チップ単体での販売だけでなく、評価ボードも多くあるため、初心者から上級者まで幅広く使われている。また開発環境も豊富で様々な環境で使えるという点もメリットである。ただ、最近は工場のストライキやコロナといった複合的要因から品薄になっており、入手性が非常に悪くなっている。

ハードはもういいや、ソフトの説明でもするか… ライントレースロボットのプログラムは、主に2手法に分けられる。オンオフ制御とPID制御(P制御、PI制御も含める)である。オンオフ制御はオンとオフを繰り返すことで目標値に近づける手法で、PID制御はセンサーの値から目標値を求めて制御量を変化させる手法である。

オンオフ制御 ライントレースでのオンオフ制御はラインが常にセンサーの間またはセンサーの真下に来るように制御をする。センサーがラインから逸脱しそうになった時に曲がることでライン追従を行う。この制御の問題点は直線を走行するときに斜めにジグザグと走るいわゆる首振り走行になってしまうことだ。 下にオンオフ制御のプログラムの一例を示す。

ライントレースのオンオフ制御のプログラムの一例を示す。これはArduino言語で開発した。センサーが1つの場合と2つの場合に分かれていて、DCモーターでの制御とコースは白い床に黒いラインで動かすことを前提としている。

センサーが1つの場合 #define Right1 6 //右のモーターの前進を指示するピンを6に設定する #define Right2 7 //右のモーターの後退を指示するピンを7に設定する #define Left1 8 //左のモーターの前進を指示するピンを8に設定する #define Left2 9 //左のモーターの後退を指示するピンを9に設定する

const int Read = 0; //センサーをReadと定義し、0番ピンに設定する

int n = 500; //センサーの黒と白を見分けるしきい値を設定する。これより高ければ白、低ければ黒になる。 int a; //センサーの示す値を格納する変数を定義する。 int lookfor(){ digitalWrite(Right1,HIGH); digitalWrite(Left2,HIGH); for(int i=0;i<3000;i++){ a = analogRead(Read); if(a<=n){ return; } } //左に曲がりながらラインを探す(3秒程度) digitalWrite(Right1,LOW); digitalWrite(Left2,LOW); digitalWrite(Right2,HIGH); digitalWrite(Left1,HIGH); while(n<=analogRead(Read)){ } return; } //ラインが見つかるまで右に曲がる

void setup() { pinMode(Right1,OUTPUT); pinMode(Right2,OUTPUT); pinMode(Left1,OUTPUT); pinMode(Left2,OUTPUT); //モータードライバに接続するピンを出力モードにする。

}

void loop() { a = analogRead(Read); if(a>=n){ lookfor(); }else if(a<=n){ digitalWrite(Right1,HIGH); digitalWrite(Left1,HIGH); delay(300); //センサーの下にラインがあったら真っ直ぐ進む } }

センサーが2つの場合 #define Right1 6 //右のモーターの前進を指示するピンを6に設定する #define Right2 7 //右のモーターの後退を指示するピンを7に設定する #define Left1 8 //左のモーターの前進を指示するピンを8に設定する #define Left2 9 //左のモーターの後退を指示するピンを9に設定する

const int Read1 = 0; //左側のセンサーをRead1と定義する。 const int Read2 = 1; //右側のセンサーをRead2と定義する。

int n = 500; //センサーの黒と白を見分けるしきい値を設定する。これより高ければ白、低ければ黒になる。 int a,b; //センサーの示す値を格納する変数を定義する。

void setup () { pinMode (Right1,OUTPUT); pinMode (Right2,OUTPUT); pinMode (Left1,OUTPUT); pinMode (Left2,OUTPUT); //モータードライバに接続するピンを出力モードにする。 }

void loop () { a = analogRead (Read1); b = analogRead (Read2); //センサーの値を読んで変数に格納する。 If (a<=n) { digitalWrite (Right1,HIGH); digitalWrite (Left2,LOW); delay (1000); //左側のセンサーがラインを認識したら1秒間左側に曲がる。 } else if (b<=n){ digitalWrite (Left1,HIGH); digitalWrite (Right2,LOW); delay (1000); //右側のセンサーがラインを認識したら1秒間右側に曲がる。 } else { digitalWrite (Right1,HIGH); digitalWrite (Left1,HIGH); delay (500); //それ以外の場合は0.5秒間だけ直進する。 } }

P制御 P制御とは日本語で比例制御と呼ばれるもので、目標値との差から制御量を決定する。目標値との差によって制御量を変化させられるため、オンオフ制御に比べてより柔軟制御が可能になる。しかし、入力に対して制御量が1つしか得られないため、周囲の環境に対して柔軟な対応ができない。

PI制御 P制御(比例)に、I制御、すなわち積分を加えたものである。I制御とは、P制御での問題点だった、目標値になかなか届かないとき(=目標値との誤差が長い時間小さくならないとき)に制御量を大きくするというものである。これによってよりスムーズに目標値へ近づけられる。ただ、制御量が大きくなりやすいため、目標値を超えてしまうオーバーシュートがしばしば発生する。ライントレースでは急なカーブなどといった、目標値の急激な変化に対応ができ、コースアウトが起こりにくい一方で、PI制御のオーバーシュートは直線での首振り走行につながる。よって、直線での速度低下すなわちタイムの増加につながってしまう。

PID制御 PI制御で問題となったオーバーシュートを防ぐための仕組みである。PI制御に加えてD制御、すなわち微分制御を加えることで制御量の急激な変化を防ぐ。その仕組みは、制御量に急激な変化が起こった時にそれに反する微分ゲインを制御量に加えることで制御量の変化を抑えるというものだ。これにより、なめらかな制御ができるようになり、目標値へ素早く追従するようになる。ライントレースでは曲線から直線に移るときに首振りを起こしにくく、安定した走行ができる。

こんな感じで書きました。Markdownで見出しになっちゃうんで#difineの#を全角にしています。クソ雑ですけどこれが本文です。なんか間違っていることもある気もするけどそのままで行きます。あはっ。注意としてはArduinoのプログラムは結構雑です。理論的には動くはずみたいな感じ。あとAトラックの課題は結構変わってるみたいですね。

次にジュニア開発ゼミの課題。結構雑です。

問1 あなたが普段使っているソフトウェアのうち、ネットワークと通信を行うものをいくつか教えてください。また、それらのソフトウェアがどのような通信を行っているのかについても一緒に教えてください。

Word 編集したドキュメントを自動で保存する機能。ドキュメントを編集すると、その変更内容をOneDriveへ自動的にアップロードする。共同編集機能では、変更内容をドライブにアップロードするのと同時に、他の編集者のパソコンに変更内容をダウンロード、反映させる。(共同編集機能は、かなりラグが大きい。多分、自分が保存したときに他の編集者の変更内容をダウンロードしている。) YouTube ホーム画面ではユーザの閲覧履歴などから、そのユーザの好みと思われる動画を探し出して表示する。このときに、サムネイルや動画投稿者のアイコンといった画像がサーバ側からクライアント側へと送られる。また、Web版ではJavaScript,Pythonといった言語で書かれたフロントエンドのテキストファイルも同時に送られる。 動画再生時にはHTML5のストリーム機能を使って動画を読み込みながら動画を再生する。 Fusion360(3DCAD) 様々な物をモデリングしたり設計したりする。(私はロボットの製作の時に使う。) このアプリはそれぞれのアカウントにクラウドのサービスがついており、クラウドにアップすることでバックアップとして保存したり、他のプロジェクトメンバーとデータを共有したりできる。(オフライン時でも保存したファイルが使用できることから、ファイルはローカルディスク上にも保存されていることと考えられる。) 保存するときにアーカイブファイルをクラウドにアップする通信、他のメンバーが作ったデータを開くときにクラウドからダウンロードする通信を行っている。 Discord/Slackといったチャットアプリ 通信を行うものとして、チャット機能と通話機能を取り上げる。 チャット機能ではメッセージを送ったら、その内容をサーバに送る。逆に誰かが何かを送ると、その内容をサーバから読み込んで表示する。メンションなど通知が必要なときには、プッシュ通知を行うサーバからエンドユーザデバイスに通知を行う。 通話機能ではエンドユーザー間で通信を行うP2P通信ではなく、サーバを介して行われる(らしい)。Discordにおいての話だが日本サーバーが無かった時代、日本とシンガポールで通信のシャトルランをしていた模様。それのせいで割とラグが大きかった。 通話アプリの通信としてCentralized server modelというのがよく使われる。サーバ側で全員の通話をまとめて、エンドユーザーに送りつけるというものだ。当然サーバ側には大量のトラフィックが押し寄せることになる。しかしエンドユーザー側にとってトラフィックは、自分の話した内容と他の人が話した内容の音声の受信であるから、会話に参加する人数が増えても、通信量が増えないというメリットがある。これによって、ユーザーに快適なグループ通話が提供される。 (LINEもこの方式を採用していることがエンジニアリングページに書かれている。)

問2 HTTP / HTTPSはどのようなものか、教えてください。また、HTTPとHTTPSを比較したとき、それぞれの長所と短所について、あなた自身で考えて、あなたの意見を教えてください。

HTTP(Hypertext Transfer Protocol)…主にHTML文書などのテキスト文書の送受信に用いられる。Webサーバといった用途で使われることが多い。通信の開始はクライアント側からしか行えない。クライアント側から送られてくるリクエストに対して、サーバ側がレスポンスを返すのが一般的。HTTP通信では、平文での通信を基本とし、暗号化せずに通信を行う。HTTPの中での認証方式としてHTTP認証があり、ユーザー名やパスワードなどで認証を行うが、セキュリティ面で十分でないといわれており、安全性を求めるのであれば、HTTPSを用いて行うほうが望ましい。このHTTP認証はローカルネットワーク上でWi-Fi機器の設定などに用いられる。

HTTPS(Hypertext Transfer Protocol Secure)…内容はHTTP通信と変わらない。HTTPSはHTTP通信をよりセキュアに行うためにHTTP通信をSSL/TLSプロトコル上で行うものであり、厳密にいえば、HTTPSプロトコルではない。HTTPSとHTTPの大きな違いは、はHTTPでは通信を平文で行うのに対し、HTTPSは通信を暗号化された文で行われることだ。そのため個人情報などの機密性の高い情報を入力した際、第三者が通信を傍受したとしても、通信の情報が流出することや、入力した情報が改竄されることなく相手側へと届けられる。このような技術がオンラインショッピングといった日々の生活を便利にしている。この通信の秘密を守るためには、次のようなことを確認しなければならない。

  1. クライアントまたはサーバが送信した情報を誰にも盗聴されずに相手側へ送られる。

  2. クライアントまたはサーバが送信した情報をそのまま改竄されることなく相手側に届ける。

  3. その情報を送る相手が偽物ではないということを確認する。

まず、①にある通信の機密性について述べる。通信の機密性を保つためには、通信を暗号化しなければならない。暗号化するためには鍵を用いる。HTTPSにおいては、共通鍵暗号方式と公開鍵暗号方式を用いて暗号化する。公開鍵暗号で共通鍵を共有し、暗号通信を行う。 ②を確認するためには、送信した情報がオリジナルのものであるかを調べればよい。オリジナルかどうか確認するためにはメッセージ認証コードを用いる。メッセージと二人の共有鍵から計算されたMAC(メッセージ認証コード)値と送信元から受信したMAC値が一致していることを確認することでそのメッセージの正真性を確かめられる。 ③を確認にはデジタル署名を用いる。サーバから送付されたSSLサーバ証明書をクライアント側のブラウザに搭載されているルート証明書で署名を確認する。それによってSSLサーバ証明書を検証する。

HTTPS通信の確立/TLSハンドシェイク HTTPS通信のClient Helloから共通鍵暗号で通信を始めるまでの流れを書く。

  1. ClientHello クライアントがサーバに送付する。内容は現在時刻(UTC)を表す4バイトにクライアントランダムと呼ばれる乱数28バイトが続く32バイトのデータ、過去に使われた通信経路を再利用するときに使うセッションID、接続しようとしているサーバのドメイン、そしてクライアントが使用可能なバージョン、暗号スイート、圧縮方法である。

  2. ServerHello ブラウザのハンドシェイクに対して、サーバ側もハンドシェイクレコードを返信する。サーバはClient Helloの中からサーバが選択した暗号スイート、32バイトのセッションID、サーバーランダムと呼ばれる予測不可能性を持った乱数を送信する。

  3. Certificate サーバが、サーバのSSL証明書をクライアントに送信する。サーバの証明書から始まり、それに署名している認証局の証明書が順番に続く。匿名で通信を行う場合には、サーバは証明書を送信しない。クライアント側は送られてきた証明書の正当性を検証し、サーバが信頼するに値するかを確認する。同時にクライアントは公開鍵を入手する。

  4. ServerKeyExchange Diffie-Hellman鍵交換など両者が情報を共有する形で鍵を交換する際に、サーバが必要な情報を送信する。RSA鍵交換など、情報が必要ない場合は送られない。

  5. ServerHelloDone Server Helloから始まる一連のメッセージの終わりを示す。

  6. ClientKeyExchange ClientKeyExchangeメッセージと共に暗号化したプレマスターシークレットを送る。暗号スイートがDiffie-Hellmanなど必要な場合はDiffie-Hellmanの公開値など共有する値も送信する。プレマスターシークレットはクライアントが作った乱数で、これからマスターシークレットが計算される。さらに、マスターシークレットから、対称暗号の鍵、メッセージ認証コードの鍵、GCMモード・CCMモードで用いる初期化ベクトルの一部を作り出す。

  7. ChangeCipherSpec(クライアント→サーバ) クライアントが暗号の変更をサーバに宣言する。ここからは、合意した暗号の通信を行う。また、ChangeCipherSpecメッセージはハンドシェイクプロトコルではなく、暗号仕様変更プロトコルのメッセージである。

  8. Finished(クライアント→サーバ) 暗号化された状態でハンドシェイクプロトコルの終了を示す。Finishedには送受信したヘッダのハッシュが全て入っており、復号化して確認することで第三者に改竄が行われていないかを確認できる。

  9. ChangeCipherSpec(サーバ→クライアント) サーバ側も暗号切り替えのメッセージをクライアントに送る。

  10. Finished(サーバ→クライアント) サーバ側もFinishedを返すことでハンドシェイクが終了する。

これによってクライアントはサーバの正しい公開鍵を入手し、サーバを認証できた。 サーバとクライアントは暗号通信に使う共有鍵を得ることができた。 サーバとクライアントはメッセージ認証コード用の共有鍵を得ることができた。

HTTPS通信が守れないもの HTTPSが守るのはあくまでも通信が暗号化されてから復号化されるまでであり、暗号化される前の情報や復号化された後の情報はHTTPSでは守れられない。そのため、個人情報などを入力している間に画面を見られるなどにより、その情報が盗まれるかもしれない。また、送られてきた情報を復号したサーバが情報を安全に保管することや、情報を使用した後に破棄するなどの対策を取らなければ、サイバー攻撃などによって、サーバに保管される情報が盗まれることも十分にありうる。他にも、HTTPS通信を行うサイトであっても悪意のあるサイトかもしれない。そのようなサイトに個人情報を送るなどということしてしまえば、簡単にその情報を悪用されてしまう。自ら利用するサービスが安全なものか確認しなければならない。

HTTPS/HTTPそれぞれの優位性 HTTP…HTTP通信の利点は、証明書なしにWebサーバを構築できるということだ。HTTPS通信を行う上では、SSL証明書が必要である。証明書を取得には金銭が必要であり、サーバの維持費が余分にかかる。またHTTPS通信は通信の暗号化、復号化が必要になる。そのためサーバ、クライアントそれぞれに多少ながらも負荷をかけることになってしまう。そのため、通信する情報の機密性が低い場合や、サーバのスペックが低い、処理の高速化を求める時などに、HTTPSよりもHTTPを選択することが有効であると考えられる。一方、HTTPの短所は情報をそのまま通信することである。HTTPはHTTPSに比べて、その安全性が低いというのは当たり前のことである。そのためHTTPは、オンラインショッピングやオンラインバンクを使用するなどに向いてない。 HTTPSHTTPS通信の利点は、何よりも通信の秘密を守れることである。通信の秘密を守れることは、個人情報などの機密性が高い情報を通信する上で大切だ。そのため、HTTPS通信は様々なサービスに使用される。昨今使われているAmazonを代表するオンラインショッピングや様々な場面で利用される決済サービスは成り立たないだろう。このように、現代においてセキュリティの高いHTTPS通信は不可欠な存在だといえる。一方、HTTPS通信の短所は維持費の高騰と処理の低速化である。大企業などがHTTPSを構築する際には費用負担は誤差の範囲かもしれない。しかし、個人がブログなどをHTTPS化する場合には、SSL証明書の発行や維持にかかる費用は大きな負担になることもある。また通信の暗号化の処理に時間がかかってしまう場合もある。ただ、この問題は楕円曲線暗号など短い鍵長で高い安全性を構築できるので大きな問題になるとは考えにくい。

問3 あなたはプログラミングをしたことがありますか。もしある場合、どのようなものを作ったか、言語は何を利用したか、規模はどの程度か(おおざっぱな行数で構いません)について教えてください。また、お気に入りの言語があれば教えてください。

中学1年生の時にライントレースロボットをつくりました。出力はDCモーター、入力は赤外線センサで、マイコンとしてArduinoを使いました。制御としてはオンオフ制御を基本に、入力値によって出力値を何段階かに分類しました。これによってロボットとラインの誤差によってモータの速度が変わるようになりました。また、オンオフ制御で問題となるオーバーシュートを軽減できるようにしました。言語はC++で行数は100行程度です。 ライントレースの後にDCモーターだけでなく、サーボモーターやステッピングモーターを回すことにチャレンジしました。サーボモーターではI2C通信でサーボモーターを複数制御できるモジュール(PCA9685)を使い、マイコン上でのI2C通信の仕方を習得しました。ステッピングモーターではモータードライバーに周波数の異なるパルスを入力する必要があったのでPWMの周波数の変え方を習得しました。 中学2年生の夏ごろから、ロボカップジュニアのレスキュー日本リーグの出場を考えるようになりました。レスキューではライントレースのコース上に障害物などがあるため、単純なライントレースの制御だけでなく、様々な条件分岐が必要となり、大変でした。また、PID制御といった今まで使わなかった制御も取り入れました。言語はC++で行数は800行程度です。プログラミングとハードウェアの製作をどちらも一人でやりました。

問4 このゼミではキャンプ期間中に実習として、あなたの作りたいものをプログラミングしてもらいます。あなたはどのようなものを作成しようと思いますか。どの言語を使用するかなど、実装方法の案があれば一緒に教えてください。後ほど変更することも可能ですので、現時点での考えを記入してください。

Pythonを使ってラズベリーパイでレトロゲームを作りたいです。マウスやキーボードといったインターフェイスによる操作でなく、GPIOを使った独自の入力機器を導入したいと思っています。また、ただ単にオフライン上でゲームを作るのではなく、P2Pなどを使い、複数人でプレイできるようにしたいです。

今読み返すと結構雑ですね。仕方ない。あと問2は問題にきちんと答えてない気もする。こんな感じで課題を書きました。参考になれば幸いです。