SWEet

A Software Engineer Is Eating Technologies

2週間ほどのベトナム滞在記

お久しぶりです。学校の留学プログラム、みたいなもので2週間ほどベトナムハノイに行っていました。

今回はそこでの経験を書き起こしておこうと思います。

そもそもなんで行ったのか

そもそもなんで留学なんか行ったの?というお話ですがそれは研究室配属の時に教授に「君プログラミングそれなりにできるみたいだし院行くから春休み暇だよね!まさにベストスウィートだよ!」と激押しされ、さらに渡航費用も成績のおかげで2万~4万で済むということでホイホイ釣られたというわけですね。実際に大した予定もなく、英語でコミュニケーション取ってアプリ開発というのも良い経験になりそうだなと思い、今回の滞在に繋がるという次第です。

滞在先での目的

では現地で一体何をするかというと「BLEを使ったAndroidアプリケーション開発」です。BLEはBluetooth Law Energyの略だったはず。 事前の勉強会ではBLEにおける、サーバーのような役割をもつPeripheral(今回はAndroid側です)とクライアント的な役割のCentral(今回はRaspberry PiのNode.jsプログラム)の解説を受けました。スマホアプリ開発に関してはiOSを少し触った程度ではありましたが大体一緒だったので仕様の把握にはそこまで手惑いませんでした。問題はNode.jsの理解です。 正直javascriptがなんとなく苦手で今まで避けてはいたのですが今回いい機会だったので片っ端からソースを読んで使用するライブラリのGitHubのソースもしっかり理解しました。おかげでコールバックを少し理解できました。

と、まぁここまでが事前準備です。実際に何を作るかは現地で他の外国人の方と話し合って決めます。

着いたはいいけど…

さて、6時間のフライトの末に着いたそこはまさに発展途上国。溢れるバイク、雲から太陽が顔を覗かせることはほぼ皆無。青空?なにそれ美味しいの?状態の街でした。歩道は普通にバイクが走るし道の舗装もがたがたです。日本の電車に乗ってる人たちがそのままバイクに乗っていると思ってもらえばその交通量の多さが想像できるでしょうか? 

泊まるところも泊まるところで控えめに言って牢屋のようだなと。初日にはお湯も使えず冷水しか出ない。なので他の部屋にシャワーを借りにいくという事態になっていました。

ベッドも寝返りをうつたびにギシギシと結構大きな音を立て、掛布団はなく、どう見てもシーツだろこれっていう感じの薄い布で初日の夜を明かしました。 正直初日にしてもう日本に帰りたいと思っていました。

気を取り直してプロジェクトスタートです

文句を言おうが朝はやってくるもので泊まっている寮からはタクシーを使って学校にいきます。「タクシーとか贅沢してんじゃねえよ」と憤慨する方もいるかもしれませんがベトナムのタクシーは2キロ走ってもらっても150円ぐらいで済みます。超安いです。 そんなこんなで学校に着き、軽く他の現地学生の方や留学生の方たちと自己紹介を済ませてプロジェクトメンバーが決められます。

今回の僕たちの班は3人でした。内訳としては僕、同じ日本人(Rさん)、ナイジェリアからの留学生(Eさん)でした。 他にも3つほどチームがあり日本人とベトナム人の混成チームです。

メンバーも決まったとこで何を作るかという話になりました。僕はあらかじめ考えていた「脱出ゲームとかで使えそうなスマホアプリケーション」を提案しました。詳細は後述します。

まぁぶっちゃけ拒否られるかなーなんて思ったりもしてましたけど意外とすんなり受け入れてくれたので決定しました。

プロジェクトの概要

ではプロジェクトの概要をざっくばらんに書いてみます。 まず、何をするシステムかというと「raspberry piに近づいてアプリを起動するとクイズが配られるのでそれを解いて得点ゲット!」という非常にチープなものです。構想自体はCTF4bで誰かが問題を解くたびにブザーが鳴っていてそれがラズパイで管理してるというものから着想しました。ただそれを実装してみると意外とめんどくさい。

f:id:kk_river108:20170315200818j:plain

上の写真はシステムのアーキテクチャを図で表現してみたものです。 大きく分けて3つのコンポーネントがあります。

  1. ラズパイ node.jsのプログラムが走ってます。nobleというライブラリを用いて片っ端からAndroid端末をサーチして条件が合致しているようであればJSON形式のクイズをバッファーに変換してandroid送信します。JSONデータは別ファイルに保存してます。

  2. Android javaで書いてます。まずこいつが「今ここにいますよー」的な宣伝をして、そいつをラズパイが検知して、問題拾って、ユーザー作るorログインして、問題解いて正解か否かを判断してユーザー情報更新のリクを別サーバーに送信するって感じです

  3. JsonAPIServer 自作したAPIサーバーです。ユーザー情報(ユーザー名、ID、スコア)を保持しています。一般的なGET,POST,PUTリクエストを受け付けます。Node.jsで書いていてmongoDBでコレクションを保存しています。

すごく大雑把でこんな感じです。実は最初はAPIサーバーを使わずに普通にMySQLとかで済ませるつもりでした。しかし、Androidアプリから外部DBサーバーにアクセスするのがすごく面倒くさくて(まる1日格闘してコネクションエラーとかで無理でした)Httpリクとか使うAPIサーバーだったらそこまで面倒くさくないだろうということでこの形に収まりました。

役割分担としてはラズパイ側はEさんに、画面UIと効果音とかをRさんに、APIサーバーの作成とAndroidAPIサーバーのコネクション、その他JSONデータのパースやその処理は自分が担当しました。

作業日数は実質的には7日ほどでしたが無事完成させることはできました。

思わぬ伏兵

開発の方自体はそこまで問題ではなかったのですがしかし全てがうまくいくことなんて当然ないわけで…

7日目ぐらいに高熱を出しました。その3日前から休日だったのですが休日という名の観光だったので体力的に全く休むことができず恐らく疲労によるものだと思いました。日本から持ってきた解熱剤をがぶ飲みしてなんとか1日で復帰しましたが頭痛や腹痛は帰るまで続いていました。観光自体は楽しかったですがやはりどこかでストレスは溜まっていたのかもしれません。自己管理不足です。

そして最終発表へ…

ぶっ倒れそうになりながらもなんとかプログラムを完成させ動作確認もしっかりでき、あとは最後のプレゼンだけでした。

しかし、英語でのプレゼンなんて当然したこともなかったので台本しっかり作って5,6時間練習してようやくそれっぽく仕上げられました。日本語だったら…なんて考えもありましたがそれはそれ。しっかり他の皆さんと同じ土俵でいい発表をしようと思いました。

本番は多少つまりながらも伝えたいことは伝えられたと思います。しかし、問題はそのあとの質問タイム。ベトナム人の先生の英語での質問が全くと言っていいほど何を言っているのかわかりませんでした。見かねたEさんが返答してくれましたがとても悔しかったです。 英語は引き続き自分の重要課題ですね。

と、そんなこんなで発表は終わり自分は「燃え尽きちまったぜ。真っ白にな…」状態でした。

f:id:kk_river108:20170315205846j:plain

発表は午前だけだったので午後からは自由時間で他のみんなは桜祭りとやらに行っていたのですが自分は寮の部屋で一人発表の反省とプログラムの確認をしていました。もうなんか何も動きたくなかったですね。

ベトナムに来る前からプログラムの開発と発表のことしか頭になかったのでそれが終わったら本当に抜け殻になってました。もしかして自分は仕事人間の才能があるのではないかと自覚した瞬間でした。 畢竟、ここまでガチでやったのは僕だけなんじゃないかと思います。自惚れだとは思いますが。

帰国へ

色々ありましたが二週間ほどをなんとか生きて過ごし、ついに帰国となりました。 今帰国してから3日ほど経ちますが日本は素晴らしい国ですね。帰ってきてから次の日に親子丼を食べに行ったのですが美味しすぎて心が慈愛に満ち、すべてを穏やかな心で見ることができるくらいでした。

と、まぁ冗談はここまでにしておいて今回のベトナム滞在で得たものは非常に大きかったです。英語でコミュニケーションを取るということ。違う環境下での体調の管理。プレゼンの仕方。まだまだ学ぶことは沢山あります。自分は韜晦するような振る舞いが苦手なのでいつも全力でやりますがそれ故に自分に足りないものが痛いほどわかるのはある意味利点だと思います。 4月にはTOEICの試験があるのでとりあえずそこに向けてしっかり勉強しておきたいと思います。

柄にもなく長文をしたためてしまいましたがここまでお付き合いしていただきありがとうございました。 今回はこのあたりで筆をおかせていただきます。

アナグラム判定メソッドの実行速度を比較してみた

今回は前回の続きといいますか、似たような問題に対する実装を複数パターンあったのでその速度を比較してみました。

問題

二つの文字列が与えられた時、片方がもう片方の並び替えになっているかどうかを決定するメソッドを書いてください。

前提条件:空白や大文字小文字も区別する。文字コードはASCIIコードだけで構わない。

というわけで書いてみました。

実装コード

static boolean MyisAnagram(String word1,String word2){
        int sumCode_1=0;
        int sumCode_2=0;
        
        if(word1.length()!=word2.length())
            return false;
        
        for(int i=0;i<word1.length();i++){
            sumCode_1 += word1.charAt(i);
        }
        for(int i=0;i<word2.length();i++){
            sumCode_2 += word2.charAt(i);
        }
        
        if(sumCode_1 == sumCode_2){
            return true;
        }
        else{
            return false;
        }
        
    }

あ、今回はjavaです。Eclipseで書いているので書いてる途中に間違えがすぐわかるので便利です。

上記のコードは自分が完全に0から考えたメソッドです。

文字列の文字コードを全て足し合わせて一致しているならアナグラムであると言えます。

中々スマートに書けたかなとは思います。

次に解答例としてあった二つの実装パターンをご紹介します。

static String sort(String s){
        char[] content = s.toCharArray();
        java.util.Arrays.sort(content);
        return new String(content);
    }
    
    static boolean permutation(String s,String t){
        if(s.length() != t.length()){
            return false;
        }
        return sort(s).equals(sort(t));
    }
static boolean permutation_2(String s,String t){
        if(s.length() != t.length()){
            return false;
        }
        
        int[] letters = new int[256]; //文字コードの仮定;
        
        char[] s_array = s.toCharArray();  
        for(char c:s_array){
            letters[c]++;
        }
        
        for(int i=0;i<t.length();i++){
            int c = (int)t.charAt(i);
            if(--letters[c] < 0){
                return false;
            }
        }
        return true;
    }

1個目はsortメソッドを作成し、二つの文字列を整列してから比較しています

2個目のメソッドは文字コードのリストをboolで作って出現したら1に、二個目の文字列を判定して、存在したら-1して0より小さくなったらその時点でfalseというのは面白いですね。

比較結果

メインメソッドを以下のように実装し実行時間を計ってみました。

public static void main(String[] args){
        long start = System.nanoTime();
        MyisAnagram("word","wo rd");
        MyisAnagram("word","fugafuga");
        MyisAnagram("word","rdow");
        long end = System.nanoTime();
        System.out.println("Processing time:" + (end - start) + "ns");
        
        start = System.nanoTime();
        permutation("word","wo rd");
        permutation("word","fugafuga");
        permutation("word","rdow");
        end = System.nanoTime();
        System.out.println("Processing time:" + (end - start) + "ns");
        
        start = System.nanoTime();
        permutation_2("word","wo rd");
        permutation_2("word","fugafuga");
        permutation_2("word","rdow");
        end = System.nanoTime();
        System.out.println("Processing time:" + (end - start) + "ns");
    }

結果は以下のとおりになりました

MyisAnagram(自分の実装) permutation(解答例1) permutation_2(解答例2)
13927ns 226304ns 5590ns

自分のは2位でしたね。悔しい。やはり全て足し合わせてから比較して結果を返すのと、比較しつつ結果を返すので差がついてしまったのでしょうか。 解答例1の方はコードもスマートでしたがやはり関数呼び出しが入る分遅くなってしまったのでしょうか。

文字列操作を弄るのは楽しいですね。 次回もまた何かプログラムを載せると思います。なにか御指摘ありましたら是非お願いします。

今月はまさかの2回更新できました。すごい

C言語のポインタインクリメントの話

新年あけましておめでとうございます。 今年は特に勉学への時間を費やしたいと思います。

さて、最近は競技プログラミングというか一からプログラミングとコンピュータの仕組みについて改めて勉強しているので今回は そこでふと疑問に思った点について書いてみました。

それはC言語のポインタの仕様です。

仕様というよりはコンパイラの解釈の方なのですが・・・ なにはともあれまずは次のCで書いたソースをご覧ください

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void A_reverse(char *str);

int main(void){
  char str[] = "abcdef";
  A_reverse(str);
  return 0;
}

void A_reverse(char *str){
  char* first=str;
  char* end=str;
  char tmp;
  int i,count=0;
  if(str){
    while(*end){
      ++end;
    }
    --end;

    while(str<end){
      tmp = *str;
      *str++ = *end;
      *end-- = tmp;
      count++;
    }
    printf("%s\n",first);
  }
}

このソースコード、まぁ読めばわかると思いますが文字列を逆に置換するものです。

str[]に文字を設定し、A_reverseメソッドでポインタを張り替え置換します。

ここで何が引っかかったかというと

while(str<end){
      tmp = *str;
      *str++ = *end;
      *end-- = tmp;
      count++;
    }

このループ部分の

*str++ = *end;
*end-- = tmp;

この辺りです。 まず、strには文字列の先頭のアドレスが、endには文字列の終端が格納されています。 endは上の処理でヌル文字の一個手前のアドレスを指すようにしています。(今回の文字列をわかりやすくすると'[a][b][c][d][e][f][¥0]'でendは'[f]'を指します)

そしてもう一つ説明としてこの処理が属するwhileループは先頭と終端からお互いのアドレスを張り替えていき、中央で張り替えを中止します。

a b c d e f str→a end→f

f b c d e a str→b end→e

f e c d b a str→c end→d

f e d c b a

strのアドレスがendより大きくなったのでここで終わり!

となっています。この張り替えの処理が

      tmp = *str;
      *str++ = *end;
      *end-- = tmp;

です。

その時重要なのがポインタ演算子の評価順です。

上記のソースの *str++ = *end の部分ですがこれだけパッと見ると、strをインクリメントしたアドレスにendのアドレスを代入する って僕は思ってました。

ですが、実際には

strの指すアドレスの内容をendのアドレスの内容に変更 → strインクリメント という流れらしいです。ややこしい

しかも最初のstr書き換えた後にstrをインクリメントしたらそれってendのアドレスから一個進むってことじゃねえの?って思ったら、なんと*str++と書くことでインクリメント前の値を取り出して参照変更して複写、そしてアドレスをインクリメントするそうです

なんというかスマートなコードではありますが少しわかりづらいので結構議論のタネになったりするそうです。

こういう記法は後置記法というそうで、*++strというような前置記法もできます。

この場合はインクリメントしてから値を取り出すという処理のようです。

これはコーディング問題の一つだったのですが思わぬ落とし穴があったので取り上げてみました。

ちなみにこれ以外にも落とし穴はあってメイン関数で宣言している str[] を *strで宣言したりするとプログラムがBus error 10という忌まわしい文字を吐いて落ちます。

というわけでC言語を書き始めて3年以上が経っても未だに嵌る時は嵌るといったものでした。1時間ぐらい調べました。恐るべしポインタ。

大学の授業ではそこまで詰まった記憶はないのですがやっぱりまだまだ詰めが甘いですね。 常に精進しろというお達しだと思ってがんばります。

それでは今回はこの辺りで筆を置かせていただきます。

SECCON2016に少しだけ参加

土日に開催されたSECCON2016に素人ながら参加したので少しだけ解けた問題について

writeupなんて言うほどでもないのでタイトルにはつけてないです

Vigenere

 Vigenere

k: ????????????
p: SECCON{???????????????????????????????????}
c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ

k=key, p=plain, c=cipher, md5(p)=f528a6ab914c1ecf856a1d93103948fe

 |ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
-+----------------------------
A|ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
B|BCDEFGHIJKLMNOPQRSTUVWXYZ{}A
C|CDEFGHIJKLMNOPQRSTUVWXYZ{}AB
D|DEFGHIJKLMNOPQRSTUVWXYZ{}ABC
E|EFGHIJKLMNOPQRSTUVWXYZ{}ABCD
F|FGHIJKLMNOPQRSTUVWXYZ{}ABCDE
G|GHIJKLMNOPQRSTUVWXYZ{}ABCDEF
H|HIJKLMNOPQRSTUVWXYZ{}ABCDEFG
I|IJKLMNOPQRSTUVWXYZ{}ABCDEFGH
J|JKLMNOPQRSTUVWXYZ{}ABCDEFGHI
K|KLMNOPQRSTUVWXYZ{}ABCDEFGHIJ
L|LMNOPQRSTUVWXYZ{}ABCDEFGHIJK
M|MNOPQRSTUVWXYZ{}ABCDEFGHIJKL
N|NOPQRSTUVWXYZ{}ABCDEFGHIJKLM
O|OPQRSTUVWXYZ{}ABCDEFGHIJKLMN
P|PQRSTUVWXYZ{}ABCDEFGHIJKLMNO
Q|QRSTUVWXYZ{}ABCDEFGHIJKLMNOP
R|RSTUVWXYZ{}ABCDEFGHIJKLMNOPQ
S|STUVWXYZ{}ABCDEFGHIJKLMNOPQR
T|TUVWXYZ{}ABCDEFGHIJKLMNOPQRS
U|UVWXYZ{}ABCDEFGHIJKLMNOPQRST
V|VWXYZ{}ABCDEFGHIJKLMNOPQRSTU
W|WXYZ{}ABCDEFGHIJKLMNOPQRSTUV
X|XYZ{}ABCDEFGHIJKLMNOPQRSTUVW
Y|YZ{}ABCDEFGHIJKLMNOPQRSTUVWX
Z|Z{}ABCDEFGHIJKLMNOPQRSTUVWXY
{|{}ABCDEFGHIJKLMNOPQRSTUVWXYZ
}|}ABCDEFGHIJKLMNOPQRSTUVWXYZ{

最初に解いたのはヴィジュネル暗号。なんだけどこれ普通にpをmd5でハッシュ化してるので演算ツールにハッシュ値を入力して逆演算させればFLAGが出てきた 本当はキーをプログラム書いて特定して復号するのが正解なのかな?

VoIP

2問目はVoIP

VoIP
Extract a voice.
The flag format is SECCON{[A-Z0-9]}.
voip.pcap

パケットのキャプチャファイルが手に入るのでwiresharkで開くとRTPパケットが沢山。シーケンスから音声データに戻すと英語でフラッグを喋っているので聞き取ってFLAGを獲得、のはずがフラッグ部分の SECCON{9001I??}となって最後の2文字が何回聞いてもZAにしか聞こえなかった。orz

正解はSECCON{9001IVR}だったらしい…

basiq

basiq
What is admin's password?☺
http://basiq.pwn.seccon.jp

adminの本当のパスワードは何かという問題。パスにadminと追加して入力するとbasic認証が出てくる。SQLインジェクションの問題かな?って思ったのでpasswordに ' or 'A'='A'と入力したら入れたけど多分違う。結局FLAGまでたどり着けず時間切れ。この問題100点なのに解けてるチームかなり少なくてビックリ。他の参加者の方のwriteupに期待

pwnとかexploitとかも解いてみたかったけど全然わからなかった! もっと色々勉強しようと思います><

最近

お久しぶりです。いつ更新しようかなー、明日かなーなんて考えてるうちにいつの間にか前回から2ヶ月近く経ってました。

なんというかネタがなかったわけじゃないんですがいざ書くとなると急にめんどくさくなってきたしまったんです…

というわけで今回は(逃げの)近況報告会に致します。

今まで何回かブログは作ったんですけどそのたんびにすぐ飽きて忘れてそのまんまっていうことが多かったので今回はなるべく継続いきたいです><

さて、最近なにやってるかというと勉強してます。

学校の授業なんかではjavaサーブレットjsppostgresql使ってシステム一つ作ってみようっていうのをやったりしたんですがフルスタックのWebフレームワークの強さを実感させられました。

しばらくサーブレットjspには触れたくないです。

あとはひたすらに自学自習といった感じです。と言っても根詰めするのが苦手なのでのんびりです。空いた時間にはゲームしてます。FF15面白かったです。

で、何を勉強してるかというとまずは英語。できるといろいろ便利なので洋書読んだり、プログラミング言語の英語のドキュメント読んだりしてます。

わからない単語や熟語は随時google先生や単語帳へ!!って感じです。

次にOSの勉強ですね。こちらはLinuxカーネル部分のソースを少しずつ紐解いて全体像をより詳しく把握するようにしています。

なんでそんなことやってるんだって言われると何ででしょうね… 面白そうだったから?でしょうか…

まぁ低いレイヤのことを理解すれば自ずと上の部分も理解しやすくなるだろうという浅ましい考えが透けて見えますがそこはノータッチで

次にPythonです。pythonはCTF等のセキュリティ関連でよく使われるので是非言語仕様を把握しておきたかったので勉強してます。

この言語面白いですね。機械学習とか興味なかったのですが色々調べ始めてしまっています。Web関連の方でもDjangoに触れてみたら便利だなーなんて思ってました。

pythonはCTFの問題において文字列の扱いや2、8、16進数に対しての各エンコードなどが他の言語に比べても柔軟に扱えるイメージがつきました。

という感じで色々勉強している「つもり」ではあるのですが学び調べていけばいくほど新しく知らないことが沢山でてきたてんやわんやな日々です。

学校の方で研究室の配属も決まり、研究テーマも決めなくてはいけない時期が近づいてきましたが、興味のある分野が多すぎて最終的に一つに絞るというのが非常に苦しいです。

時間があれば色々できますがそうも言ってられませんね。なるべく寝る前とかにベッドでどんな研究がいいかなーなんて考えてます。そしていつの間にか寝ています。

というわけで最近の報告でした。

今回はこのあたりで筆をおかせていただきます。

次の更新を年明けまでにできるかな…

SC試験受けてきました

次は認証に関する話の続きと言ったな あれは嘘だ  

1か月以上空きました。色々勉強してたらなんか更新するの忘れてました。

さて、10月16日に情報処理技術者試験があったので自分は兼ねてより勉強()していた情報セキュリティスペシャリストの区分で受けてきました。

ちなみに自分は基本も応用も持ってません。そこの知識は必要ですが資格として欲しいわけじゃないしSCしか眼中になかったので…

端的に言って結果としては落ちたと思います。怖いので自己採点はしてません。結果が公表されてからしっかり反省しようと思うので許してください。

一応今回の自分の受けた感想を書いておきます。

午前1

相当広い知識範囲を問われます。基本情報から応用までの知識がかなり比重として重いなと思いました。 正直ここら辺での経営とかの知識はほぼ参考書チラ見程度だったのできつかったです。所感としてはギリ6割いってるかな?って感じでした

午前2

セキュリティ関係の知識がたくさん問われます。時事ネタも多少。自分としてはこっちの方がしっかり解けた感じしました。多分7割程度

午後1

セキュアプログラミングや組み込みシステムのネットワーク管理、プロキシサーバを主題として社内ネットワークのマルウェア感染時の対応のうちから2つ選んで答えます。 自分はヒープオーバーフローに関するセキュアプログラミングとマルウェア感染の対応について答えました。こちらは記述の当たり方によるのでなんとも言えません。運よく6割いってないかなー

午後2

ICカードを用いた認証システムに関する問題と社内の脆弱性対策についての問題です。 過去問は結構解いたのですが今までにない傾向の午後2だったので正直問題見たときは「詰んだ」って思いましたね どっちもきつかったですが多少知識のある認証問題を選択しました。こちらも記述次第ですね…

まとめ

基本的にセキュリティというのはそれ一つで大きな分野としてあるものではなく、情報分野の様々なところにセキュリティは存在していて、それをまとめて情報セキュリティと呼んでいるだけだと思っているので広い知識分野が必須だと自分は考えています。

もちろん、例えばソフトウェアのセキュリティに関して言えばプログラミング言語の仕様、バイナリやCPUの命令セットの仕組み等まで把握してないといけません。ハードやリアルな面で言えば経営の仕方、情報セキュリティ教育の方針等枚挙に暇がありません。とどのつまり広く深く知識がないとセキュリティスペシャリストとは言えないというわけでしょうね。

SCの試験については春にもう一度受けてみようかなと思いますがほかのこともあるので3か月前になったらもう一度考えてみます。 TOEIC等もあるのでそちらの勉強も疎かにはできないのが辛いです。

最近自分は暗号技術やリバースエンジニアリングの勉強を主にしていますがそれだけではダメ。ですが全部を極めるのはどう考えても難しい。ならば取捨選択は必須ということなので改めて自分のやりたいことは何なのか、それを考えるいい機会にもなったと思っています。 進路を決定する時期にもなってきたので自分との会話をしっかりしてみようと思います。

それでは今回はこの辺りで筆をおかせていただきます。

次からはCTFとかで使う技術に関して書いてみようか…

情報セキュリティにおける認証

 今年の夏休みは十年来の友人に連絡が取れたりドラクエ夏祭りに参加したりと中々充実していた気がします。

さて、今回は現代のインターネット、情報システムにおいて当たり前のように使われている認証技術についてまとめてみました。

認証って?

認証:「一定の行為や文書の作成が正当な手続きによってなされたことを定められた公の機関が証明すること」(出典:松村明編『大辞林 第2版』三省堂

らしいです。堅苦しいですが、情報セキュリティにおいての認証には二つの要素が含まれています。それが、Authentication と Certificationです。

  • Authentication

    主にユーザーID、パスワード、もしくは生体情報などを用いて人、物、情報を識別し、その正当性や真正性を直接確認することです。通常は何らかの情報資産やシステムリソースなどへのアクセス権を管理し、アクセス制御を行っているシステムや人間と、それらに対するアクセスを要求するものとの間で直接的に認証行為がおこなれます。なのでこのような認証の方式を二者間認証という場合もあるそうです。

  • Certification

    デジタル証明書による認証に代表されるような認証局などの第三者が発行する証明書の保有をもとにその持ち主の正当性を確認すること。つまり、この方式では認証が欲しい人、それを認証する人、そしてそれに介在すいる第三者(登録管理者なんて呼ばれてます)によって認証行為が行われます。こういった場合三者間認証なんて呼ばれるそうです。辞書に載っている方の認証に近い意味を持つのはこちらでしょうか?

    「単位を教授に認めてもらう」なんていうのもCertificationに近いでしょうね(白目)

認証の分類について

先程述べたAuthenticationについて認証の対象を人、物、情報の三つに大別していました。その内容と具体例を調べてみました。

認証の種類 内容 具体例
人の認証 個人の識別を行い、事前に登録されている本人であることを確認すること ユーザーIDとパスワードによる本人認証、指紋認証
物の認証 システムやネットワークへのアクセスを要求している機器などの正当性を確認すること MACアドレスによる端末の認証、発信元電話番号による端末の認証
情報の認証 情報が不正に改変されていないことを確認すること メッセージダイジェストやディジタル署名によってプログラムやデータの改ざんの有無を確認|

所有物(ICカード、磁気カード)や秘密情報(パスワード、暗証番号)などによる認証は導入が容易で誰もが理解できるが単体で用いる場合によっては、実装や運用によってむしろセキュリティの低下につながる恐れがあります。そのため、高度なセキュリティが求められる環境やシステムなどでは二つを併用する、もしくはバイオメトリクスによる認証が用いられることが多いそうです。典型的な例としては、キャッシュカード(所有物)と暗証番号(秘密)によって本人認証を行い、銀行からお金を引き出すといったものがあります。こういった方式を二要素認証もしくは多要素認証と呼びます。

ちなみに、非常に破られにくい生体認証(バイオメトリクス認証)ですが導入のコストが非常に高いのでそこらかしこに導入するというのが出来ないのがデメリットです。

次の記事からは色々な認証方式についてまとめてみようと思います。

それでは今回はこの辺りで筆をおかせていただきます。