5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

闘魂Elixir ーー ElixirでHMACを楽しむ

Last updated at Posted at 2023-07-29

$\huge{元氣ですかーーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$

$\huge{闘魂とは己に打ち克つこと。}$
$\huge{そして闘いを通じて己の魂を磨いていく}$
$\huge{ことだと思います}$

はじめに

Elixirという素敵な関数型言語の話をします。
ElixirHMACをしてみます。

HMACは、Hash-based Message Authentication Code または keyed-Hash Message Authentication Codeの略語です。

HMAC (Hash-based Message Authentication Code または keyed-Hash Message Authentication Code) とは、メッセージ認証符号 (MAC; Message Authentication Code) の一つであり、秘密鍵とメッセージ(データ)とハッシュ関数をもとに計算される。

ウィキペディア HMAC

ElixirHMAC

こんな感じです。猪木寛至です。猪木さんです。

signed_payload = "闘魂"
secret = "123da-"

:crypto.mac(:hmac, :sha256, secret, signed_payload)
|> Base.encode16(case: :lower)

実行すると、"16fc9aface82759ece52bd84c99d8c48f7886f061789b4f97e4225241a997a27"が得られます。

最後のBase.encode16(case: :lower)は、バイナリデータを16進数の文字列(小文字)に変換しています。
:caseオプションのデフォルト値は:upperです。
16進数の文字列表現が必要かどうかはケース場合ケースだとおもいます。
必要に応じて取捨選択してください。

一体いつ使うの?

HMACは、一体いつ使うのでしょうか。

このへんです。もう少し説明を続けます。
SlackやLINEのボット(アプリ)を作る場合、SlackやLINEの方からイベントを通知してもらって受け取ることがあります。
たとえば、「◯◯さんがメッセージを送信しました」とか「△△さんがジョインしました」といったイベントです。
この通知が本当にSlackやLINEからきたものであるかを確かめるために使われます。署名検証を行うわけです。

署名検証をLINEの場合で説明します。
LINEはボット(アプリ)にイベントを通知する際に、リクエストbodyとあらかじめLINEと開発者間で決めた(LINE Developers Consoleで払い出された)Channel secretで署名を作成します。
その署名をHTTPヘッダのX-Line-Signatureに埋め込んで、ボット(アプリ)にイベントを通知(HTTP POST)します。
イベントを受け取ったボット(アプリ)でも、リクエストbodyとChannel secretで署名を作ります。そして、HTTPヘッダに含まれているX-Line-Signatureの値と比較して一致すればLINEからの通知だと判定できるわけです。

Slackの場合も考え方は同じです。v0とかtimestampとかでてきますけど、まあ同じです。

LINEのSDKで話を続けます。
LINE Messaging API SDK for Pythonを使った場合には、署名検証はSDKに隠蔽されています。

app = Flask(__name__)

configuration = Configuration(access_token='YOUR_CHANNEL_ACCESS_TOKEN')
handler = WebhookHandler('YOUR_CHANNEL_SECRET')


@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature) # ①
    except InvalidSignatureError:
        app.logger.info("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'

import文は省いています。
ここでお伝えしたいことは、①のhandleメソッド内で署名検証が行われている、隠蔽されているという点をお伝えしたいです。
handlerは初期化時にChannel secretを指定しています。
handleメソッドでは、リクエストbodyとHTTPヘッダのX-Line-Signatureが渡されています。
情報はそろいましたので、handleメソッド内で署名の検証ができるわけです。

LINEのボット(アプリ)を作る際に、私はサンプルの通りに言われた通りになんとなくで指定していたChannel secretの必要性がわかりました。


話をNervesに転じます。

Build a Weather Station with Elixir and Nerves』という本の中では、IoTデバイスから通知を受け取るPhoenix APIサーバーとの間の通信でHMACを使うことが紹介されています。HMACを使うことで自身の管理するIoTデバイスからのPOSTなのだということを確かめられるという寸法です。

よいリンクも紹介されていましたので貼っておきます。

Phoenixで、オンライン決済サービスStripeからのWebhookを受け取る実装例が書かれています。

さいごに

ElixirHMACしてみました。
HMACを一体いつ使うのかを説明しました。署名検証に使われます。


闘魂とは、 「己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことである」 との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。
アントニオ猪木さんのメッセージから元氣をもらったものとして、それを次代に語り継ぎ、自分自身が「闘魂」を体現するものでありたいとおもいます。


$\huge{元氣ですかーーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$
$\huge{1、2、3 ぁっダァー!}$

5
4
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
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?