2017-04-11 9 views
1

python-joseのJWT実装を使用して認証目的でJWTトークンを生成しています。異なるサーバが同じパラメータを使用して異なるJWTトークンを生成する

私たちは、同じ秘密特許請求の範囲、およびアルゴリズムためKubernetesと我々は、複数のポッドを持っているとき、時々、私たちが得る異なるトークンにドッカーコンテナに私たちのバックエンドを実行しています。私はtouchindex.wsgiスクリプトを実行すると、私の開発環境上の単一のコンテナでもこれを実行しました。

ポッド1:

>>> jwt.encode({'key': 'value'}, 'secret', algorithm='HS256') 
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ2YWx1ZSJ9.FG-8UppwHaFp1LgRYQQeS6EDQF7_6-bMFegNucHjmWg' 

ポッド2:

>>> jwt.encode({'key': 'value'}, 'secret', algorithm='HS256') 
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJrZXkiOiJ2YWx1ZSJ9.JPIDicqvQ6GAh14yE2yZ3wnZQ0LiLNTTRDtJgLZcn98' 

私はこれを引き起こしている可能性がものを見るためにコードに深いダイビングを取って、自分に不利な何かを見つけることができませんでした。一言で言えば、ここでのコードが何をするかです:

  1. はどの=
  2. は、ペイロード({'key': 'value'})のjson.dumpsを行い取り外し、アルゴリズムのヘッダ({'typ': 'JWT', 'alg': 'HS256'})のjson.dumpsを行うと、Base64のようにエンコードし、任意=除去、Base64のようにそれをコード '再度除去し、Base64のようにそれをsecretキーでHMAC256を使用してエンコードS
  3. サインencoded_header.encoded_payloadを任意=
  4. を連結前STに署名結果、encoded_header.encoded_payload.encoded_signature

この時点で、私はこれを引き起こしているのか分かりません。私は、HMACやSHA256のPython実装で何らかのバグがあると思っていますが、それはむしろ起こりそうにない...手がかりは?

注:のベースであったpyjwtでバグを再現しました。

答えて

4

これは、Python辞書が順序付けられていないために発生します。 2つのJWTをデコードすると、ヘッダー部分の順序がトークンごとに異なることがわかります。

{ 
    "typ": "JWT", 
    "alg": "HS256" 
} 

{ 
    "alg": "HS256", 
    "typ": "JWT" 
} 

これは、順番に署名が異なるようになります異なるようにヘッダをbase64エンコードを引き起こします。

しかし、これらの両方とも、まったく同じクレームセットの有効なトークンであり、両方とも正常に検証する必要があります。 JWT仕様には、それと同等のクレームセットが同等のJWT出力をもたらすべきであると指示するものは何もない。

注:私はpython-joseライブラリの著者です。

+0

欠けている部分を見つけるための乾杯。これはJWT自体の問題ではなく、むしろ私がそれを使用していた方法の問題です。私が読んだものに基づいて、ヘッダー部分を保存して取り除くのはうまくいくと思った。基本的には、任意のペイロードをエンコードしてヘッダーを抽出することで 'FIXED_HEADER'を生成していました。生成されたトークンは、返される前にヘッダーが取り除かれ、デコード前に再び前に追加されます。これが署名検証の失敗につながる理由は今や明らかです。これ以上のヘッダーは削除されません。 – PLPeeters

関連する問題