2
1

認証で具体的にどんなアルゴリズムでやっているかご存じですか?
私は全然知りませんでした。😐

Railsのdeviseを使ったら勝手にやってくれるから特に気にも留めていませんでした。
しかし、プライベート開発中に仕組みを勉強する機会がありましたので、
学習した内容を記事にさせて頂きます。

記事がいいなと思ったらtwitterのフォローもお待ちしております‼
https://twitter.com/takeshi_program

はじめに

本記事は以下の読者様が対象です。

  • プログラミング初心者

本記事のゴール

  • トークンによるセキュリティ向上 +αデータベースリソースの負荷軽減ができる理由を把握できる。

トークンとは?

トークンは暗号文字列です。
そのため、復号化の方法知らなければ、意味のない文字列です。

認証トークンの使い方について

認証トークンはログインが成功した際にサーバーから発行されクライアントに付与されます。
そして、クライアント側は付与されたトークンを毎回のリクエスト時に本体データと一緒に送付します。
サーバー側はそのトークンを見て有効期限内の有効なトークンであれば
正常なレスポンスを送り、異常であれば再度ログインを求めるためのページを返すのが一般的です。

トークンの有無による認証方法の違い

  • トークンなし(emailとpasswordだけ)の場合

トークンを使わない場合はトークンの代わりに毎回リクエストにemailとpasswordを付与して送ります。
その都度サーバー側はDBへリクエストを行い、passwordを取得し、passwordが同じものかを照合します。
image.png

照合結果がOKであれば、適切なデータをレスポンスします。

単純なため仕組みですが、このプロトコルのデメリットは
仮に第三者にemailとpasswordを盗聴された場合に、ユーザーが盗まれた事に気づきpasswordを変更する必要があります。
それまで、第三者にデータを盗まれ続けます。

image.png

  • トークンありの場合

トークンの場合、ユーザーが盗聴に気づかなくても一定時間が経過したらトークンが無効になるため、トークンを使った方が仮に情報を盗まれても被害を小さくできます。
image.png
image.png

(もし期限のないトークンの場合はユーザーが盗聴に気づくまで盗まれ続けます)

トークン詳細について

トークンへの期限の実装方法ですが、
そもそも暗号化というのはある文字を意味のない文字列に変換する処理です。
暗号化する前の文字の中に期限を入れていれば期限の情報を内包した文字を暗号化できます。
それを復号すれば期限情報を取得できるため、現在時刻と比較すればよいという事です。

以下がRubyで暗号化、復号化するコードです。

require 'openssl'
require 'securerandom'

def encrypt(data, key, iv)
  cipher = OpenSSL::Cipher.new('AES-256-CBC')
  cipher.encrypt
  cipher.key = key
  cipher.iv = iv
  encrypted = cipher.update(data) + cipher.final
  return encrypted
end

def decrypt(encrypted_data, key, iv)
  cipher = OpenSSL::Cipher.new('AES-256-CBC')
  cipher.decrypt
  cipher.key = key
  cipher.iv = iv
  decrypted = cipher.update(encrypted_data) + cipher.final
  return decrypted
end

# 32バイトのランダムな鍵を生成
encryption_key = SecureRandom.bytes(32)
iv = OpenSSL::Random.random_bytes(16) # Initialization Vector (IV)

# 暗号化
data_to_encrypt = '{email: "test_user", limit: "2023/12/24"}' #トークンの生成
encrypted_data = encrypt(data_to_encrypt, encryption_key, iv)
puts encrypted_data

# 復号化
decrypted_data = decrypt(encrypted_data, encryption_key, iv) #トークンの生成
puts decrypted_data

データベースリソースの負荷軽減

トークンがあればサーバー側はトークンの有効期限をチェックするだけよく、DBからユーザー情報を取得する必要がなくなるため、データーベースへのリクエストの回数が減り、DBリソース負荷を軽減できるメリットもあります。

おわりに

今回のサンプルコードはemailとlimitのプロパティしか渡していませんが、ここに[create, update, delete, read]などを入れることで認証だけでなく、認可の情報もトークンに載せて送ることができます。
すごい技術ですよね~
おそらくAWSのAMIやcognitoRuby on Railsのdeviseもそのような仕組みなのでしょうね。

また発見があれば記事にしたいと思います。
ありがとうございました。👍

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1