djangoで辞書やリストに署名する

django.core.signingモジュールの関数を利用して、辞書やリストなどのデータに署名することができる

from django.core import signing
value = signing.dumps({'name': 'brainstorm'})
print value
# => 'eyJuYW1lIjoiYnJhaW5zdG9ybSJ9:1UZ9GI:0qqInzB49WPUPL9m9LKBcrgLOq0'

data = signing.loads(value)
print data
# => {u'name': u'brainstorm'}

# 署名を改ざんするとエラー
value = value+ 'a'
data = signing.loads(value)
# => BadSignature: Signature "0qqInzB49WPUPL9m9LKBcrgLOq0a" does not match


署名にはデフォルトでsettings.SECRET_KEYがキーとして使用されるが、別に指定することもできる

value = signing.dumps({'name': 'brainstorm'}, key='my_secretkey')
print value
# => 'eyJuYW1lIjoiYnJhaW5zdG9ybSJ9:1UZ9Nf:RTlGt2tlln43uThoKXejnnYPoV8'

# キーを指定しないとエラー
signing.loads(value)
# => BadSignature: Signature "RTlGt2tlln43uThoKXejnnYPoV8" does not match

data = signing.loads(value, key='my_secretkey')
print data
# => {u'name': u'brainstorm'}


saltはデフォルトで'django.core.signing'が使用されるが、これも指定できる。

value = signing.dumps({'name': 'brainstorm'}, key='my_secretkey', salt="hoge")
print value
# => 'eyJuYW1lIjoiYnJhaW5zdG9ybSJ9:1UZ9Q5:65N2oDU4yZ0UV_37is0W3kTmO9o'

data = signing.loads(value, key='my_secretkey', salt="hoge")
print data
# => {u'name': u'brainstorm'}


django.core.signingのdumps、loadsで実現できるのは、改ざんの検知と、認証である。

データの改ざんが行われると、loadsする際にBadSignatureエラーが発生するので検知できる。(完全性)
またsecret_keyは秘密にされるので、loads可能な署名付きデータを送信してくる相手は、secret_keyを使用可能な相手であることを確認できる。(真正性)

一方、signing.dumpsで出力した値は、単純にbase64encodeしたjson文字列を含むので、データを盗聴された場合は容易に復元できる。= 機密性には寄与しない

        value = signing.dumps({'name': 'brainstorm'})
        print value
        # => 'eyJuYW1lIjoiYnJhaW5zdG9ybSJ9:1UZE2l:lmC_I_P1ly1BtDiEyqgzT5T3hbU'
        
        decoded = b64_decode(value.split(':')[0])
        print decoded
        #=> {"name":"brainstorm"}

参考 : 暗号による署名 ― Django 1.4 documentation