車輪の国、 TouchDevelopの少女 tmyt COD沖縄 13/5/11
about me • tmyt
• 東京らへんで組み込みシステム開発してます
• 最近はXamarin 2.0とか触ったりしてます
• 好き: C++, C#, Delphi, ZSH
• Twitter: @tmyt • Github: tmyt
今日はなすこと
� TouchDevelopとはなんぞや
� TouchDevelopで学習する � bit演算 � ハッシュ関数 � 認可プロトコル
Touch develop is … 何
� Microsoft Reserchの研究成果
� プログラミングを学習するためのツール
� 主なターゲットはタッチデバイス
� キーボードがなくてもボタン押してるだけでOK
こんなの DEMO
TouchDevelopの特徴
� 『やりたいこと』が主体
� 各種命令は高度に抽象化されている
� ひとつの命令で画像を表示したりできる
� あえて言うならCISCアセンブリ言語
� 成果物はStore AppsなどにExportできます
TouchDevelopで
� 出来ること � 文字や画像を表示する � 四則演算する � 三角関数を使う
� 出来ないこと � ビット演算をする � IntやCharなどを使い分ける � 53bitを超える整数を扱う
今日の目標 TouchDevelopでOAuth認証をしてみる
あるひ
� *「TouchDevelopでOAuth認証ってできる?」
� 僕「できるんじゃない?」
OAuth認証に必要なもの
� HMAC-SHA1ダイジェスト
� Authorization: OAuth ヘッダ
� 文字列をUTF-8バイト列として処理
� 現在時刻をEpoch Timeで扱う
TouchDevelopでできる?
� HMAC-SHA1ダイジェスト � SHA1ハッシュ
� 生成できない � HMAC
� 生成できない
� Authorization: OAuth ヘッダ � できる
� 文字列をUTF-8バイト列として処理 � できない
� 現在時刻をEpoch Timeで扱う � できない
TouchDevelopでできる?
� SHA1ハッシュ � 生成できない
� ビット演算ができない � ライブラリとしての実装もない
� HMAC � ハッシュアルゴリズムが無いため実装がない
� 文字列をUTF-8バイト列として処理 � UTF-16文字列を変換する関数は実装がある
� 現在時刻をEpoch Timeで扱う � 現在時刻をDateTime型で取得出来るので変換する
OAuthするために
1. Epoch Timeを実装する
2. ビット演算を実装する
3. SHA1ハッシュを実装する
4. HMACダイジェストを実装する
5. UTF-16 → UTF-8変換を実装する
6. OAuthを実装する
Chapter.I Epoch Timeの取得
Epoch Timeって?
� いわゆるUNIX時間
� 1970年1月1日からの経過秒数として表現
� タイムゾーンのオフセットは存在せず常にUTC
TouchDevelopの時刻表現
� TouchDevelopでは時刻を表現できる
� イメージとしてはJavaScriptのDate型
� もちろんEpoch Timeへの変換は不可
Epoch Timeへの変換
1. UTCで現在時刻を取得する
2. 1970年からの経過日数を単純に計算する
3. 日付×36400+0時からの経過秒数を計算する
� あれ、TouchDevelopって閏年の判定ができない � それぐらいは軽く作りましょう
� ここまでで約1時間
Chapter.II ビット演算
ビット演算とは
� ある値をビット列で表現しそのビットごとに論理演算を適用する
� 例えば � 15(10) AND 20(10) = 4(10) � 15(10) OR 20(10) = 31(10) � 15(10) XOR 20(10) = 27(10)
� C言語などではビット演算演算子が存在する
ビットの配列へ変換
� ビット演算には2進数への変換が必要 � 手計算で2進数へ変換する場合と同様に実装する
List<int> ToBinary(int n) { var b = new List<int>(); while (n != 0) {
b.Add(n % 2); n /= 2;
} return b.Reverse().Take(32).ToList();
}
ビット演算を実装する
� 任意の数値をビット配列に変換できればあとはビットごとにAND, OR, XOR, NOTを実装するだけ
� SHA1ハッシュの計算にはビットシフトも必要 � 同様にして実装します
� だいたいここまでで30分
Chapter.III SHA1ハッシュ
SHA1ハッシュ
� Secure Hash Algorithm 縮めてSHA
� ハッシュ関数のひとつ
� 入力に対し一意な160bitの値を出力する
� 余談 � SHA1はNISTが2010年よりDeprecatedとしています � 今後はSHA256を使うのをおすすめします
SHA1の生成
� こんな雰囲気です
� バッファを64の倍数に拡張
� バッファを8bitごとに区切り � StepA, B, C, Dの4パターンで演算 � 格段の値を合計
� 32bitの値5個を連結して160bitに
TouchDevelopで実装する
� 先ほど作ったビット演算が活躍します � AND, OR, XOR, SHR, SHL � 右回転シフトも必要なので作ります
� 定数に16進数は使えないのですべて10進にします � コピペも出来ないので間違えないように入力します
� 加算結果は最大で33bitになります � TouchDevelopの数値型は53bit精度の浮動小数 � 4294967295(0xFFFFFFFF)とANDを取って切り捨てる
Chapter.IV HMACダイジェストを計算する
HMACダイジェスト
� メッセージとキーから固定長のデータを生成する
� サーバから提供されたデータに対してパスワードを使って演算し、それをサーバに送信とかして使う � パスワードはユーザ/サーバ両者に既知の値 � サーバはデータ/パスワード共に既知であるためパスワードを直接ネットワーク上に流さずとも検証可能
� 結局内部でSHA1とか使ってます
HMAC-SHA1
� HMACの内部アルゴリズムとしてSHA1を使う
� アルゴリズムの流れ � 鍵と0x5cをXORで演算 … ① � 鍵と0x36をXORで演算しメッセージと結合 … ② � ②へハッシュ関数を適用 … ③ � ①と③を結合 … ④ � ④へハッシュ関数を適用しMACとする
TouchDevelopで実装する
� SHA1はすでに実装しました
� 文字列からバイナリ生成はすでに実装しました
� ビット演算はすでに実装しました
� これらよりアルゴリズムを忠実に実装します � 飽和演算なども不要なため素直に実装できます
Chapter.V UTF-8文字列を作る
UTF-8文字列
� インターネットの世界ではUTF-8が流行
� TouchDevelopの内部はUTF-16です
� OAuthでアクセスする先は大抵UTF-8
� UTF-8文字列が必要になります
文字列の扱い
� TouchDevelopでは文字列はUTF-16
� UTF-8のINT配列にするには? � web→url encodeを使って変換する � UTF-16のINT配列を作って変換する
� 最終的には後者で実装しています � 後者の方が断然速いです
UTF-16からUTF-8への変換
� UTF-8 ⇔ UTF-16は相互に変換可能 void to_u8(int c) { if(c < 128) chars.Add(c); else { if(c < 2048) chars.Add(((c >> 6) & 31) | 192); else { chars.Add((c >> 12) | 224); chars.Add(((c >> 6) & 63) | 128); } chars.Add((c & 63) | 128); } }
Chapter.VI OAuthを実装する
OAuthとは
� 認可プロトコル
� 認証プロトコルではない � 第三者にリソースへのアクセスを許可する
� 第三者がユーザのCredentialを知ることはできない
OAuthの仕組み
� ConsumerはProviderに仮トークンを要求
� Consumerは仮トークンを使って認証URLを要求
� Userは認証URLで自分のアカウント使いログイン � 得られたVerifierをConsumerへ通知
� ConsumerはVerifierを用いProviderへ実トークンを要求
� Providerはトークンを発行しConsumerのアクセスを認可する
結構めんどくさい
大抵ライブラリがあります
� 有名な言語には大抵OAuthの実装はあります
� C++, Java, C#, Objective-C, PHP, Perl, Ruby, …
� OAuthの手実装は面倒なのでライブラリ使うのがおすすめです
� TouchDevelopにはそんなものありません
TouchDevelopでの実装
� OAuthで必要なものはこれまでに用意しました � HMAC-SHA1 � Epoch Time � UTF-8
� 仕様書通りに実装するだけです � できあがったものはTouchDevelopライブラリとして公開済みです
DEMO できたものがこちら
まとめ
� TouchDevelopでプログラミングを学習しました
� TouchDevelopらしい使い方ではありません � あえて実装することで理解が深まります � C言語の本でビット演算実装しないでしょ?
� 制限された環境だと楽しくなってくる
� 学習するための車輪は惜しまない