YubiKeyのワンタイムパスワードでZIPを暗号化してみた

こんにちは。

「YubiKeyを導入したのに、ログイン認証でしか使わないんだけど…」
「手元にあるYubiKeyをもっといろんなコトに使ってみたい…」
「YubiKey導入済みのお客様へ、自社アプリを他社と差別化して提案したい!」

せっかく導入したYubiKeyをログイン認証だけにしか使わないなんて、もったいない!

こんなお悩みありませんか?

上司やユーザ、もしくは自社の営業部門からそんな意見殺到中のアプリケーション開発者に向けて、『YubiKeyをログイン認証以外でも簡単に使える』ことを紹介します!

この記事は以下の悩みがある人におすすめ!

  • YubiKeyはログイン認証以外で使えるの?
  • YubiKeyを使ってアプリケーションを作ってみたい
  • YubiKeyを導入中のお客様に自社製品を提案したい

本記事を読み終わる頃には、「あっ、そんなに簡単にYubiKeyを使ったアプリケーションを作れるのね」と思えるようになりますので、ぜひご覧ください!

1 概要

今回はYubiKeyのワンタイムパスワード(以降OTP)で、ZIPの暗号化と復号ができるアプリケーションを作ってみます。

準備するもの

  • YubiKey
  • DAuth
  • Bashが動く環境(筆者の環境:AWS EC2のAmazon Linux2)

開発言語は手軽に試せるシェルスクリプトでやってみたいと思います。もちろん、他の開発言語でも作れますのでご安心ください。

2 アプリケーションの仕様

いろいろな方法で実現できると思いますが、今回は下記の方法で作ります。

お気付きでしょうか? 
”ZIPで暗号化””ZIPで復号”の入出力は変わっていません。

つまり、今回作るアプリケーションは、YubiKeyのワンタイムパスワードをZIPの暗号化(復号)に使うパスワードに変換するアプリケーションと言えます。

せっかくなので、ZIPの暗号化に使うパスワードの下記のようにセキュリティ強度を高めてみましょう。

  • 毎回異なるパスワードを生成する(同じパスワードは使わない)
  • パスワードの複雑さは64文字のランダム値にする

日常、ZIPで暗号化するときに、こんな仕様のパスワードを使うことはなかなかありません。単純に覚えられないからです。

しかし、今回ユーザは暗号化、復号するときYubiKeyしか使いません!
パスワードを覚える必要がないので、どんなに複雑でも問題ありませんね。

さて、実際に作ろうとしたときに、下記の2つの機能が必要になりました。

  • YubiKeyのOTPが正しいかの検証
  • ランダムなパスワードの保管先

これをゼロから自前で作ると大変なので、DAuthを使います。

「え!? DAuthってユーザ認証のサービスじゃないの?」

はい。実はDAuthはオンラインデータベースとしても使えるのです!

3 DAuthをデータベースとして使う

DAuthは開発者が簡単にYubiKeyやFIDOを使ってアプリケーションを開発できるためのサービスです。
そのため、オンラインデータベースのような使い方もできます。
仕組みは非常にシンプルで、KVSや連想配列のようなイメージで使えます。

データベースに登録するとき

データベースにデータ(JSON形式)を登録するときのイメージは次の通りです。

データを登録するときに必要なものは3つです。

  • キーワード (データを検索するときに使うキー:プライマリーキー)
  • データ (JSON形式)
  • データへのアクセスを許可するデバイス情報(YubiKey ID:OTPの先頭12桁)

通常のデータベースであれば、キーワードとデータだけです。DAuthでは、データへのアクセスを許可するデバイス情報も必要になります。

データベースからデータを取得するとき

データベースからデータを取得するときのイメージは次の通りです。

データを取得するときに必要なものは2つです。

  • キーワード (データを検索するときに使うキー:プライマリーキー)
  • データへのアクセスを許可されたYubiKeyのOTP

YubiKeyのOTPが正しいとき、キーワードに紐付いたデータを取得できます。

DAuthに登録できるデータはJSON形式です。フィールドが確定しているデータベースとは違い、開発者の用途に合わせて自由に設計できます。

例1
{
 ”name”: “taro”,
 ”age” : “22”
}

例2
{
 ”car-no”: “12-34”,
 ”color” : “red”
}

いかがでしたか。とてもシンプルな作りですよね?

  • アクセスを許可するYubiKeyのIDとデータ(JSON)を登録する。
  • 許可したYubiKeyのOTPだった場合、登録したデータ(JSON)を返す。


この2つの仕組みを使うだけで、YubiKeyを様々な用途で簡単にアプリケーションへ実装することができます。

4 アプリケーションの作り

事前準備として、DAuthで下記の作業を行います。

APIキーの発行
 DAuthのWeb APIを使うときの認証に必要です。32文字の文字列です。
使用するYubiKeyの登録
 DAuthで使用するYubiKeyは、事前に情報を登録する必要があります。

いずれも簡単な作業ですので、ここでの説明は省略します。

次にプログラムから呼び出す外部アプリケーションをインストールします。
必要なアプリケーションの一覧です。

  • zip
  • curl
  • jq

インストールされているかの確認方法

$ zip -v
Copyright (c) 1990-2008 Info-ZIP – Type ‘zip “-L”‘ for software license.
:

$ curl -V
curl 7.61.1 (x86_64-koji-linux-gnu) libcurl/7.61.1 OpenSSL/1.0.2k zlib/1.2.7 libidn2/2.3.0 libssh2/1.4.3 nghttp2/1.41.0
:

$ jq -V
jq-1.5

バージョンは違っていても動作すると思います。
インストールがされていない場合、各OSに合わせた方法でインストールしてください。

ZIPの暗号化プログラム(スクリプト)

プログラムの処理は下記の通りです。


ZIP暗号化のスクリプトは下記になります。

#!/bin/bash

# Usage : zip.sh file otp
# <API KEY>にDAuthで作成したAPIキーの値を入れる

APIKEY=<API KEY>

# 引数の解析
FILE=${1}
OTP=${2}
# YubiKey OTPの先頭12桁はデバイスID
KEYID=${OTP::12}

# パスワード(ランダム文字)生成
PASSWORD=$(tr -dc ‘A-Za-z0-9#%@&()’ < /dev/urandom | fold -w64 | head -n 1)
# キーワード(データベースのPK)生成
KEY=$(tr -dc ‘A-Za-z0-9’ < /dev/urandom | fold -w8 | head -n 1)

# DAuthのWeb APIを呼び出す(データ登録)
RESULT=$(curl \ 
 -X POST \ 
 -s \
  -H “X-DAUTH-API-KEY:${APIKEY}” \
  -H “Content-Type: application/json” \
  -d ‘{“device_id”:”‘${KEYID}'”, “key”:”‘${KEY}'”, “value”:”\”‘${PASSWORD}’\””}’ \
  ‘https://api.d-auth.com/v1/dkvs’ \
)

# Error check
if [ “`echo ${RESULT} | grep ‘errors’`” ] ; then
  echo “Error!!”
  echo “`echo ${RESULT} | jq -r ‘.errors[0].message’`”
  exit 1
fi

# 外部アプリのzipで暗号化
zip -e –password=${PASSWORD} ${FILE}.${KEY}.zip ${FILE}

次に、作成したスクリプトの動作を確認します。

$ chmod +x zip.sh
$ date > test.txt

# ZIPで暗号化します  ./zip.sh test.txt <YUBIKEY OTP>
$ ./zip.sh test.txt vvblnxxxxckrfrefvjthxxcvxxnvlckhrcxxxekcjeju

$ ls
test.txt  test.txt.Sf8f0aHc.zip  zip.sh

ファイルを説明します。

  • zip.sh  : 作成したスクリプト
  • test.txt : ZIPで暗号化する元のファイル
  • test.txt.Sf8f0aHc.zip : ZIPで暗号化されたファイル

test.txt.Sf8f0aHc.zipの”Sf8f0aHc”の部分が、DAuthからパスワードを取得するときに使うキーワードになります。

DAuthの管理コンソールから、登録されたデータを確認してみます。

赤枠の”Value”の箇所が、実際にZIPで暗号化するときに使ったパスワードです。

ZIPの復号プログラム(スクリプト)

プログラムの処理は下記の通りです。

ZIP復号のスクリプトは下記になります。

#!/bin/bash

# Usage : unzip.sh file.xxxxxxxx.zip <YUBIKEY OTP>

# ここの値を入れ替える
# <API KEY>にDAuthで作成したAPIキーの値を入れる

APIKEY=<API KEY>

# test.txt.XXXXXX.zip -> XXXXXX
ZIPFILE=${1}
KEY=$(echo ${ZIPFILE} | sed ‘s/^.*\.\([^\.]*\)\.\([^\.]*\)$/\1/’)
OTP=${2}

# DAuthのWeb APIを呼び出す(データ取得)
RESULT=$(curl \ 
 -s \
  -H “X-DAUTH-API-KEY:${APIKEY}” \ 
 “https://api.d-auth.com/v1/dkvs/yubikey_otp?key=${KEY}&otp=${OTP}”)

# Error check
if [ “`echo ${RESULT} | grep ‘errors’`” ] ; then
  echo
  echo “Error!!”
  echo “`echo ${RESULT} | jq -r ‘.errors[0].message’`”
  exit 1
fi

# DAuthのレスポンス値(JSON)からパスワードを取得
PASSWORD=`echo ${RESULT} | jq -r ‘.[0].value’`

# zipで復号
unzip -o -P ${PASSWORD} ${ZIPFILE}

次に、作成したスクリプトの動作を確認します。

$ chmod +x unzip.sh
# 解凍されたのがわかるように、”test.txt”のファイル名を”test.txt.org”に変更します。
$ mv test.txt test.txt.org

$ ./unzip.sh test.txt.Sf8f0aHc.zip <YUBIKEY OTP>
$ ls
test.txt  test.txt.org  test.txt.Sf8f0aHc.zip  unzip.sh  zip.sh

ファイルを説明します。

  • unzip.sh   : 作成したスクリプト
  • test.txt   : ZIPで復号したファイル
  • test.txt.org : 元のファイル
  • test.txt.Sf8f0aHc.zip : ZIPで暗号化されたファイル

復号された”test.txt”と”test.txt.org”を比較し、正常に復号できたのを確認してみてください。

5 まとめ

この記事では、『YubiKeyをログイン認証以外でも簡単に使える』ことを紹介しました。

今回はZIPの暗号化や復号で使うパスワードに、YubiKeyのワンタイムパスワードを使ってみました。これだけでも大幅にセキュリティ強度を上げ、かつパスワードを覚える苦痛からユーザを解放することができました。

その他にもアイデア次第でおもしろい使い方ができます。
例えば……

  • ワークフローの承認に使う。
  • 特定のYubiKeyを所持するユーザだけ、データをアップロード、ダウンロードできる。

などです。

いずれも文字列の入力だけで作れるので、開発者にとっては簡単に実装できますよね。DAuthのオンラインデータベースを上手く活用すれば、既存システムのデータベースを改修することなく実装できるかもしれません。

いかがでしたか。
YubiKeyを使ったアプリケーション開発は、イメージできたでしょうか?

DAuthならあなたが開発したアプリケーションに、YubiKeyを簡単に実装できます。「どんな種類のWeb APIがあるのか」「FIDOでも出来るのか」「もっと詳しく知りたい」などありましたら、お気軽にこちらからお問い合わせください。

最後まで読んでいただき、ありがとうございました!

このコラムにコメントする

コメントは承認制とさせていただいているため、反映まで少しお時間をいただきます。あらかじめご了承ください。

コラム一覧

お見積り・導入に関する
ご質問・サービスの詳細など
ご不明な点は
お気軽にお問い合わせください