カテゴリー: テクノロジー

パスワードに塩かけ?

こんにちは。開発担当のマットです。

今回の記事で、ウェブサービス等の開発者がパスワードを安全に保存するための塩かけ(ソルト)の概念を説明したいと思います。

むかしむかし…

大昔、ウェブサービスにアカウントを作成した際、そのウェブサービスが登録したユーザ名とパスワードをそのまま保存しました。
データベースを覗いてみると、各ユーザのユーザ名とパスワードはそのまま見れていました。

user_name password
田中 一郎 123456789
山田 太郎 hogehoge
鈴木 花子 qwertyuiop
村田 次郎 hogehoge

もちろん、サイトがハッキングされてしまった場合、全ユーザのパスワードが丸見えです。
これを使って、ログインすることもできますし、ユーザ様が別のウェブサイトで同じパスワードを利用している場合、そのウェブサイトにもログインされてしまうことは考えられます。
とても、不安全な方法でした。

ハッシングで隠す

こういう問題が明らかになった時、多くのウェブサービスがハッシングを使うようになりました。

ハッシングとは?

ハッシングとは一方的の暗号関数です。
その関数にパスワードを渡したら、暗号された文字列が生成されます。

いくつかのハッシング・アルゴリズムは存在しますが、md5 というものを使ってみると、”hello” が “5d41402abc4b2a76b9719d911017c592” に変換されます。

特徴として、似たようなものを暗号化しても、その結果(ハッシュ)が全然違います。
例:
“bat” => 5f3f4681121b460e3304a1887f42f1c3
“cat” => d077f244def8a70e5ea758bd8352fcd8
“あいうえお” => 86deb27a32903da70a7b2348fcf36bc3
“あいうええ” => 5c6a3a46075a5617cd570ee1c583e528

パスワードを直接データベースに保存する代わりに、パスワードのハッシュを保存する時代になりました。

user_name password
田中 一郎 25f9e794323b453885f5181f1b624d0b
山田 太郎 329435e5e66be809a656af105f42401e
鈴木 花子 6eea9b7ef19179a06954edd0f6c05ceb
村田 次郎 329435e5e66be809a656af105f42401e

ユーザ様がログインする際、入力したパスワードを同じアルゴリズムでハッシングして、データベースで保存されているものと一致する場合のみ、正しいパスワードと言えます。

この方法で、データベースにパスワードを直接保存することなく、ウェブサービスを作ることはできるようになりました。

…ところで、ちょっとした問題はまだあります。見えますでしょうか?

ハッシングだけの問題

上記の例で、山田 太郎さんと村田 次郎さんは同じパスワードを使いました。
同じパスワードを使っているため、ハッシュも当然同じです。

つまり、サービスがハッキングされてしまった場合、パスワードはバレませんが、「山田 太郎さんと村田 次郎さんは同じパスワードを使っています」というのがバレてしまいます。
もし、山田 太郎さんのパスワードが別の方法でバレてしまった場合、村田 次郎さんのパスワードもわかってしまいます。

あと、多くのユーザ様がいる場合、重複が多いパスワードを推測することも可能になります。
“password1” や “12345678” など、多くの人が使いそうなパスワードはあるので、重複数が多いユーザはこういうようなパスワードを使っていると言えますね。

塩かけ(ソルト)で解決

調理する時、塩を少し加えるだけで味がグッと変わりますよね。
同じく、ハッシングをする時、パスワードだけではなく、「ちょっとした何か」を加えると、全く違う結果になります。

例として、2人のユーザが同じパスワード (“password123”)を設定するとします。
そのままハッシングすると、2人とも同じハッシュになりますが、ユーザAのパスワードに「abc」を付け加えてからハッシングして、ユーザBのパスワードに「xyz」を付け加えてからハッシングすると、2人とも全く違うハッシュになります。

この「ちょっとした何か」を「ソルト」と呼んでいます。
ソルトは乱数でも、ランダムな文字列でも大丈夫です。とにかく全てのユーザに違うソルトが振られたら問題ありません。

そうすると、仮に全員が同じ「password123」を設定したとしても、データベースに保存されるパスワードが全く違います。

user_name salt password
田中 一郎 PJTBCTwz a021144f7dec828d515f372d6d239f5f
山田 太郎 5g0VkWF1 19ead4c6deca667db146d9a1c478e4d6
鈴木 花子 p9nfzkBT 411fec4ff70554cded8b48ab9bc3b8c3
村田 次郎 BoqWcL59 5487529bd4deb8003b6a46bbbaf03332

ユーザがログインする時、入力したパスワードにソルトを付け加えてハッシングすると、その結果が password として保存されている値と同じ場合、ログインをさせるという処理になります。

私のパスワードは安全ですか?

ご利用のウェブサービスが正しくソルト付けとハッシングをしているかどうかは判断しにくいですが、「パスワードを忘れました」などのリンクを押した場合、自分のパスワードがメールで送信されたら、安全に保管されていないと言えます。

パスワードを正しく取り扱っているウェブサービスはユーザのパスワードをわかる方法がないはずです。どこにも保存してはいけないデータとなります。

なので、ウェブサービスが自分のパスワードをメールで送信できる場合…アウトです。
ご注意ください。


Big O 記法

こんにちは。開発担当のマットです。

僕はプログラミングが大好きです。パソコンに自由自在にコマンドを書いて、好きなものを作れることはとても面白くて、プログラマーになった理由です。
しかし、プログラムの書き方に気を付けないと、規模を拡大することに連れ、処理がカクカクと遅くなってしまうこともあります。

この記事にて、プログラマは常に気を付けなければならない Big O 記法を紹介したいと思います。

Big O 記法とは?

Big O 記法 (別名: オーダー記法、O-記法、ランダウの記号) はドイツの数論家であるポール・バッハマンによって1894年に、彼の著書『解析数論』(Analytische Zahlentheorie) の第二巻で初めて導入されました。これに触発されてエドムント・ランダウが1909年に発明しました。

「どういうもの?」かというと、何らかの関数(何らかの機能)の規模を大きくするに連れ、その関数の処理時間がどのように伸びるか、の表記と考えてもいいかもしれません。

実例で考えると?

ゲームの例で考えましょう・・・
特定のゲームではなく、たくさんのAIプレーヤが遊ぶ戦略ゲームとか、何でもいいです。

このようなゲームのPC版のAIプレーヤーを作ろうとしましょう

このゲームで、プレーヤーが順番に遊びます。
ゲームのメモリーに、プレイヤーの順番リストがあるとしましょう。
ゲームに4プレーヤーがいるとしましょう。

O(1)

では、ゲームの一番目のプレーヤーを見つけるのに、どれぐらい時間がかかりますでしょうか?プログラムがしないといけない処理は:
・まず、プレーヤーのリストを見る。
・リストの頭のプレーヤを引き出す。
・終わり。

簡単な処理ですね。さて、プレイヤー数をなんと 10,000人にしたら、その処理がどうなるでしょう?
・まず、プレーヤーのリストを見る。
・リストの頭のプレーヤを引き出す。
・終わり。

変わりませんよね。Big O 記法では、こういう関数を O(1) と書きます。
O(1) とは、定数時間。関数に突っ込むデータの規模が大きくなっても、処理時間が変わりません。

プログラムを書く時(特に、大規模のデータを処理するプログラム)、O(1)の関数ばっかりでできることは一番望ましいです。

O(n)

次、各プレーヤに100ポイントを与えましょう!
4人のプレイヤーがいる場合、
・まず、プレーヤー1に100ポイントを与える
・次、プレーヤー2に100ポイントを与える
・次、プレーヤー3に100ポイントを与える
・次、プレーヤー4に100ポイントを与える
・終わり。

簡単な処理ですが、10,000人プレーヤーがいるとしたら、その人数分の時間がかかりますよね。これは O(n) と書きます。
規模が大きくなるに連れ、その分遅くなります。データは2倍あるなら、処理は2倍遅い。

O(n²)

次、少し難しくなりますが、このゲームに「隠れ情報」があるとしましょう。
例えば、各プレーヤーの財産が自分にも、他人にも、見られないというルール。
もちろん見られませんが、賢いAIを作るには、自分と他プレーヤーの財産を推測する関数も作りたいですね。

・まず、プレーヤー1自分の財産を推測する。
・次、プレーヤー1プレーヤー2の財産を推測する。
・次、プレーヤー1プレーヤー3の財産を推測する。
・次、プレーヤー1プレーヤー4の財産を推測する。
・次、プレーヤー2プレーヤー1の財産を推測する。
・次、プレーヤー2自分の財産を推測する。
・次、プレーヤー2プレーヤー3の財産を推測する。
・次、プレーヤー2プレーヤー4の財産を推測する。
・次、プレーヤー3プレーヤー1の財産を推測する。
・次、プレーヤー3プレーヤー2の財産を推測する。
・次、プレーヤー3自分の財産を推測する。
・次、プレーヤー3プレーヤー4の財産を推測する。
・次、プレーヤー4プレーヤー1の財産を推測する。
・次、プレーヤー4プレーヤー2の財産を推測する。
・次、プレーヤー4プレーヤー3の財産を推測する。
・次、プレーヤー4自分の財産を推測する。

数えると、 4 プレーヤーで 16 ステップが必要です。
8プレーヤーだとしたら、64ステップが必要になります。

規模を2倍にすると、4倍の処理時間となりますね。
平方関係なので、O(n²) と書きます。

他にもありますか?

限りなく、他にもたくさんの表記があります。
O(n³) もありますし、 O((n-1)²)もあります。
O(log n)もありますし、恐ろしい O(n!) もあります。

まとめ

それぞれのBig O 記法の表記の意味を暗記する必要はありませんが、プログラマーとして、何かの関数や機能やアルゴリズムを作るとき、無駄に時間が掛かるやり方でやっていないか、気を付けなければならないと思います。

この Big O 記法を常に頭にいれて開発をすると、より速やかで優れているコードは書けると思いますので、今後もこの記法を覚えてプログラミングをやっていきたいと思います。


Gmail活用のすゝめ

皆様、Gmail使っていますか?

使っていますよね。使いましょう。

Gmailは今の時代なくてはならないほど便利なメールサービスです。

今回はGmailのちょっとした便利機能についてご紹介いたします。

現代においては、何をするにしてもメールアドレスを要求されることが多いです。

そんな時、1つのメールアドレスを使い回すのが一般的かと思います。

ただ、1つのメールアドレスを使い回すことでメールの整理がしにくかったり、個人情報が流出した場合にどこから漏れたのが把握できないといった事があります。

じゃあ複数のGmailを登録するの?

それはそれで有効だと思いますが、管理が複雑になったり手間がかかるので今回は別の方法をとります。

ピリオドの利用

Gmailアドレスには、メールアドレスにピリオドが含まれていたとしても同じメールアドレスに届くという機能があります。

Gmailヘルプには以下のように記載されています。

Gmail アドレスでのピリオドの扱い

他のユーザーがあなたにメールを送信する際に、誤ってメールアドレスにピリオドを追加した場合でも、メールはあなたの受信トレイに届きます。たとえば、メールアドレスが「johnsmith@gmail.com」の場合、次のようにピリオドが含まれたメールアドレスもあなたが所有していることになります。

  • john.smith@gmail.com
  • jo.hn.sm.ith@gmail.com
  • j.o.h.n.s.m.i.t.h@gmail.com

引用元:Gmail アドレスでのピリオドの扱い

これをメールアドレスを要求された際に利用することで、この位置にピリオドがあるメールはどこで使っているメールアドレスだ、ということでフィルタリングし、整理に使うことができます。

また、迷惑メールが届いた場合には、あそこで使っているメールアドレスだからあそこから情報が流出したのか、という見当をつけることができます。

エイリアスの利用

Gmailにはメールアドレスの@の前に+○○としても、同じメールアドレスに届く機能があります。

たとえば先程の「johnsmith@gmail.com」の場合、次のアドレスも所有していることになります。

  • johnsmith+hogehoge@gmail.com
  • johnsmith+foobar@gmail.com
  • johnsmith+servicename@gmail.com

※こちらはGmailの公式ヘルプページを見つけることができませんでした。

こちらの機能についてもフィルタリングに利用することができ、サービス名を入れることでよりわかりやすいものとなります。

ただ、こちらは場合によってはメールアドレスに+(プラス)が許可されておらず、利用できない場合があります。

最後に

どちらの機能も、とてもポピュラーで便利な機能となります。

今回は受信のみの説明で、Gmail側では何も設定が必要のないものとなりますが、Gmail側の設定を行うことで送信にも利用できるようになります。

需要があるようであれば、そちらも記事にしたいと思います。


AIにオーストラリアのことを聞いてみた

こんにちは。開発担当のマットです。
私はオーストラリア生まれ育ちで、18歳の時に日本に移住しました。

もう少ししたら、人生の半分ぐらいは日本になりますので、日本とオーストラリアの似ているところ、異なっているところについて詳しいのかなと思います。
ところで、僕に聞かなくても、AIに聞ける時代になってきましたので、やってみました。

文化の違いを画像生成AIに聞いてみて、合っているかどうかを評価して見たいと思います。

食文化

まずは、食べ物の違いについて聞いてみました。
AI に「Japanese Food」を訪ねたら、何が出力されるでしょう?

Japanese Food

本当にビックリしました。
日本の料理店で出される料理そっくりです。AIの力に驚きますね。
次はオーストラリアの料理を見てみたいです。

Australian Food

この結果も素晴らしい。オーストラリアのカフェで出されそうな画像ばっかりです。

評価: 10/10

リビング

日常生活で一番重要のは、リビングの部屋かもしれませんね。
家族が集まって、一緒にご飯を食べて、テレビを見て、話し合うところです。

日本では、木材の床または畳で、こたつや食卓が主役のイメージですかな…
オーストラリアでは、絨毯で、ソーファーが主役のかな…

Japanese Living Room

思ったより「和」ですね。

Australian Living Room

いろいろとオッシャレなリビングですね。
実際にオーストラリアに絶対ありそうです。

評価: 10/10

スポーツ

スポーツはどうでしょう?
日本なら、野球や相撲のかな?

Japanese Sport

なるほどですね。
「日本のスポーツ」といえば、確かに室内スポーツが多いですね。
空手やバレーボールなど、体育館や武道館で行えるスポーツですね。

オーストラリアなら野外スポーツの方が人気のイメージありますね。
ラグビーやクリケットのかな?

Australian Sport

なんじゃこれ!w

完全にお化けになっていますね。
3脚でサッカーをするイメージは流石にない…
でも、日本のスポーツはイメージ通りですね。

評価: 6/10

自然

最後に、日本とオーストラリアの自然を試してみましょう。

日本なら、山と小川が多く、緑のイメージがあります。

Japanese Nature

まさに、イメージ通りです。
しかも、キャンピング行きたくなるぐらいのリアルさ。

オーストラリアは日本より乾燥して、広くて赤色の平地にユーカリの森または砂漠のイメージです。

Australian Nature

これも、まさにイメージ通りです。
AIは本当に素晴らしいものになってきましたね。

もう少し、砂漠っぽい画像も交じるかと思いましたけど、もしかしたら、オーストラリアの砂漠に住んでいる人が少ないので、ネットに写真データも少なくて、AIが写真が多いところ(比較的に人口が多い、森林がある地方)の写真データに影響されているのでしょう?

でも、どれも本当にオーストラリアにありそうな画像ですね。

評価: 10/10

まとめ

最近、AIは遥かに進化してきています。

文章を与えるだけで、こんなに素晴らしいものを生成できるなんって驚きますね。

今回、私は DALL·E 2 という画像生成AIを使っていました。
ご興味がある方は是非、アカウントを登録してみてください。


パスキーによる認証を体験

はじめに

2022年12月に Chrome でパスキーが利用できるようになりました。
そのことを伝えるネット記事をいくつか読んだときには、パスキーを使った認証の全体像というか仕組みというかそういうものがいまいちピンと来なかったので、もう少し詳しいことを調べつつデモサイトでその動作を体験してみました。

WebAuthn とパスキー

WebAuthn (Web Authentication)

WebAuthn は認証に関するウェブ標準の1つで、いわゆる「パスワード不要の認証」を実現する FIDO2 認証をウェブブラウザ上で実現するためのものです。

従来のIDとパスワードによる認証では、パスワード(あるいはパスワードのハッシュ)という秘密情報をサービスのサーバに預ける必要がありました。そのため漏洩のリスクがあり、漏洩してしまうと同じパスワードを使う別のサービスでも使われてしまうという問題を抱えています。

WebAuthn による認証は次のような特徴を持っています。

  • 秘密情報はユーザの手元のデバイスで保持する(漏洩のリスクが非常に低い)
  • 認証に使うクレデンシャルはサービスのドメインと紐付けられているのでフィッシングに強い
  • 従来型のログインで必要だったID・パスワードの入力や、ワンタイムパスワードの入力などが不要で、利便性が高い

WebAuthn によるユーザ登録の大まかな流れは以下の通りです。

  1. ウェブブラウザがサーバにユーザIDを送り、登録を要求する
  2. サーバがチャレンジ(検証に利用するランダムな数値列)を生成してブラウザに返す
  3. ブラウザは認証器にチャレンジを渡す
  4. 認証器は鍵ペアの生成承認を得るために、ユーザに生体認証を求める
  5. 生体認証がOKならば、認証器は秘密鍵と公開鍵のペアを生成する
  6. 認証器は秘密鍵を使ってチャレンジに署名し、署名付チャレンジ・公開鍵・クレデンシャルID(秘密鍵に紐付いたID)をウェブブラウザに返す
  7. ウェブブラウザは署名付チャレンジ・公開鍵・クレデンシャルIDをサーバに送る
  8. サーバは公開鍵を使って署名付チャレンジを検証する
  9. チャレンジの検証結果とその他のチェック(ドメインなど)がOKならユーザの公開鍵・クレデンシャルIDをユーザIDに対応付けて保存する

WebAuthn による認証の大まかな流れは以下の通りです。

  1. ウェブブラウザがサーバにユーザIDを送り、チャレンジを要求する
  2. サーバはユーザIDに紐付いたクレデンシャルIDと共にチャレンジをブラウザに返す
  3. ブラウザは認証器にチャレンジ・クレデンシャルIDを渡す
  4. 認証器は秘密鍵の利用承認を得るために、ユーザに生体認証を求める
  5. 生体認証がOKならば、認証器はクレデンシャルIDに対応した秘密鍵を使ってチャレンジに署名してウェブブラウザに返す
  6. ウェブブラウザは署名付チャレンジ・クレデンシャルIDをサーバに返す
  7. サーバは公開鍵を使って署名付チャレンジを検証する
  8. チャレンジの検証結果とその他のチェック(ドメインなど)がOKならログイン成功

重要なのは以下の点です。

  • 秘密鍵はサーバに送られず、ローカルの認証器に保存される
  • 生体認証の情報はサーバに送られず、ローカルの認証器で秘密鍵を利用するときのユーザ確認として利用される

重要な情報はローカルに有り、サーバ側で保存している情報(公開鍵やクレデンシャルID)が漏れたとしても攻撃には利用できない訳です。

パスキー

WebAuthn では基本的にウェブブラウザと認証器は同じ機器で動いていることが想定されていました(スマートフォン内蔵の指紋認証や PC の USB ポートに接続されたセキュリティキーなど)。スマートフォンで WebAuthn のクレデンシャルを生成し、記録したとします。買い替えや紛失でそのスマートフォンが使えなくなったら登録をやり直さなければなりません。また、異なる端末からログインする場合には同じサービスであってもそれぞれの端末で登録する必要がありました。

パスキーは WebAuthn のそういった課題を解決して使い勝手を向上させるための拡張です。

  • ウェブブラウザと認証器が別々の機器であっても動くようにした
  • 複数の認証器でクレデンシャルを同期できるようにした

パスキーによる認証を体験する

https://webauthn.io/ というデモサイトでパスキーによる認証を体験してみます。

登録

ユーザ名を入力して”Register”を押します。

今回はスマートフォンを利用するので「別のデバイス」を選びます。

QR コードが表示されるのでスマートフォンで読み込んで FIDO: で始まる URL にアクセスします。

パスキーの作成について確認されるので「続行」します。

スマートフォン側で生体認証を要求されます。(この画面はスクリーンショットを撮れませんでした)

ここで「このパソコンの情報を保持する」にチェックを入れておくと、認証の際に QR コードの表示(PC側)と読み取り(スマートフォン側)のステップをスキップできます。

これで登録完了です。

認証

登録済のユーザ名を入力して”Authenticate”を押します。

先程登録に使ったスマートフォンを選びます。

スマートフォン側で生体認証を要求されます。(この画面はスクリーンショットを撮れませんでした)

ログイン完了。一旦登録が完了してしまえばログインは非常に簡単です。

ここまでの手順は Linux デスクトップで行いました。
Chrome でパスキーが使えるようになったというリリース情報では Linux 版の Chrome が対応しているのかどうかいまいちハッキリしないところがあったのですが、試してみるとあっさり動きました。

この状態で、たとえば別の Windows PC の Chrome で webauthn.io にアクセスしてスマートフォンを認証器として利用して splout01 で同じ手順でログインできます。

パスキーを利用する際に Bluetooth を使って機器同士の近接をチェックしているので、PC とスマートフォンの両方で Bluetooth が有効になっていないといけません。試しに PC とスマートフォンそれぞれで Bluetooth をオフにしたところ、どちらがオフの場合でも途中で認証失敗となりました。(Bluetooth をオンにするように促される)

おわりに

従来よりも安全でパスワードの煩わしさからも解放されるパスキーには大いに期待しています。
これから対応サービスが増えていくのが楽しみです。