Redshiftのユーザー定義関数(UDF)をつくって、会員情報をソルト+ストレッチングでハッシュ化してみる
こんにちは、みかみです。
はじめに
ユーザー登録のあるシステムだと、会員IDやパスワードはアプリでハッシュ化してDBに格納するケースがほとんどだと思いますが、「今ハッシュ化していない会員IDをハッシュ化したい」「今ハッシュ化しているパスワードをソルト+ストレッチングで強化したい」などの要件がもちあがった場合、すでにDBに格納済みの会員データの更新も必要になります。
いったんDBから会員データ抜き出して、必要なところはハッシュ化して、またDBに格納して・・・だと、手間がかかるし、セキュリティ面のリスクもあるし。。
やりたいこと
- DBに格納済みの会員IDを、ソルト+ストレッチングでハッシュ化したい
- データを抜き出すことなく、DB側だけで完結させたい
- なるべく簡単に(時間をかけずに)やりたい
使うもの
- DB:Redshift
- 言語:Python、SQL
やってみた
ユーザー定義関数(UDF)を作る
Redshiftのユーザー定義関数を作成します。
他のRDBMSのストアドファンクションのようにSQLでも書けますが、RedshiftはPythonでもUDF作れます(Pythonならば、ロジック部分はDB登録前にローカル環境で動かして確認できるしv
UDF のための Python 言語のサポート | AWS Documentation
パラメータでもらった id を、ソルト(今回は、固定文字列の str-prefix と str-suffix )をつけてSHA-256でハッシュ化し、ストレッチング(とりあえず10回)して返します。
CREATE FUNCTION f_create_hush(id VARCHAR) RETURNS varchar STABLE AS $$ import hashlib prefix = 'str-prefix' suffix = 'str-suffix' id = prefix + id + suffix for i in range(10): id = hashlib.sha256(id.encode()).hexdigest() return id $$ LANGUAGE plpythonu;
テスト用テーブルとデータを準備
会員情報テーブルを作ります。
create table test_members( id varchar(20), id_hush varchar(128), name varchar(20) );
そこに、会員IDとユーザー名データを登録します。
insert into test_members (id, name) values ('12345678', 'mikami'), ('98765432', 'sakila'), ('67895432', 'gopher');
データを登録していない id_hush カラムには、後ほど、UDFで作成したIDのハッシュを入れる予定です。
こんなデータが入りました。
dev=# select * from test_members; id | id_hush | name ----------+---------+-------- 98765432 | | sakila 12345678 | | mikami 67895432 | | gopher (3 行)
会員IDのハッシュ値をテーブルに格納
先ほど準備した会員情報テーブルに、ソルト付きハッシュ値をストレッチングしたIDを加えます。
dev=# update test_members set id_hush = f_create_hush(id); UPDATE 3
データを確認してみると・・・
dev=# select * from test_members; id | id_hush | name ----------+------------------------------------------------------------------+-------- 98765432 | 9c3e333395e6cc03041f7260302ee307b8608c7592243435b679a66f64f3732a | sakila 12345678 | 5601d1ca89fff92f0039ba96517586064b14f3631cc08d5985eb04d74e95deef | mikami 67895432 | d94ea325b6315c111441433e2e07212a45f7263a7614104a46fc6a9c20baa6d6 | gopher (3 行)
ちゃんとハッシュIDが入りました!
おわりに
思ってたより簡単に、RedshiftのUDF作成&使用できました。
ただ、今回自分はrootで確認してます。ユーザーによっては USAGE ON LANGUAGE PLPYTHONU 権限の付与が必要とのことです。
UDF のセキュリティおよび権限 | AWS Documentation
また、今回はhashlibしか使ってませんが、使いたいPythonライブラリがRedshiftに入っていない場合には、自分でインポートする必要があるそうです。
カスタム Python ライブラリモジュールのインポート | AWS Documentation
ライブラリ自分でインポートできるのならば、ハッシュ化に限らず、Pythonで書ける処理をUDFにおまかせすることできちゃうんですね@@v