GAEのデータストアに、PyCryptoの暗号化した文字列を登録、呼び出してみた

GAEでも何でもサービスを行うときには、ユーザーの情報を保持する場合は扱いは気を使うと思います。
特に漏れてはいけない情報としてはパスワードや利用者に通ずる情報も。
そのようなサービスでは情報の暗号化は必須でしょう、そこでGAEで暗号化したデータをどう扱うのか調べていました。

GAEのPython版にはPyCryptoがある

最近になって、Google App EngineではPyCryptoのモジュールが追加されたそうです。意外と簡単に済む?
ローカル環境では、GAE本体には内蔵されずに、ローカル環境のsite-package内のモジュールを使うそうで、インストールする必要があるとか。

さて、環境は整ったので、早速暗号復号をさせてみます。ここでつまずいたのが暗号化した文字列(バイト列)をどう扱うかということです。
データストアのプロパティでは、StringPropertyが一般的でしょうか。ですがこれを使うことはできないそうです。暗号のバイト列は文字コードの意味を持つことはありませんし。
そこで、そのままのバイトの情報を保存するプロパティを使います。バイト列を保存するプロパティはByteStringPropertyかBlobPropertyを使いますが、バイト数が少ないならByteStringPropertyで良いかな?
型とプロパティ クラス - Google App Engine - Google Code


参考サイトを確認しつつ、こんな感じで暗号復号ですか。
[Python] pycrypto で暗号化してみる - With skill and creativeness

#SDK ConsoleのIntearactive Consoleより
from google.appengine.ext import db
import Crypto.Cipher.AES as AES

class CryptData(db.Model):
    encryptdata = db.ByteStringProperty()

CRYPT_KEY = "need 16 multiple"

cryptobj = AES.new(CRYPT_KEY, AES.MODE_ECB)

message = "message is hogehoge hugahuga."

#messageは29文字(byte)なので、32byteに桁埋め
cryptdata = CryptData(
        encryptdata = cryptobj.encrypt(message + "XXX")
        )
cryptdata.put()

decrypt_message = cryptobj.decrypt(cryptdata.encryptdata)

print "message :" + message
print "criphertext :" + cryptdata.encryptdata
print "decrypt_message :" + decrypt_message[:-3]
#console output

message :message is hogehoge hugahuga.
criphertext :1eVG����y�T���(�ũT�%��S�w�b
decrypt_message :message is hogehoge hugahuga.

こんなふうに保管されています。


実はローカル環境でしかテストしていないので、もしかしたらデプロイした時に本番環境で問題があるかもしれません。
(本番環境でのモジュールのインポート先がどこにも書かれていないので、そのままで大丈夫だとは思いますが)


ASE利用時は、暗号化時のキー(ここでのCRYPT_KEY)は16,24,32byteの文字列を設定します。、暗号化の対象文字列は桁数は16倍のbyte数が条件です
さらに、PyCryptoでは必要ならば、元の文字列の桁埋め(パディング)を行わなければ行けません。
(こういうのって自動でやってくれると思ってましたが)
元の桁数が固定なら、足らない部分を手動で埋めても良いでしょうか。文字列を直接つなげてもいいし、桁を変えやすくprint文でやるとか。

print "%(#)014d" % {"#":0} 
#みたいにやると、0の文字列が14桁出力される

元が可変する場合は、可変文を計算して文字列を作ってやらないと行けませんね。面倒だったのでやってませんが(汗


ともあれ、暗号化されたバイト列の登録、呼び出しはそれほど難しい問題ではないということで。
暗号化時に必要なキーの情報はどう扱うべきかが悩みます。設定ファイルを作ってそこから読み込むとかでいいのかな。