web-dev-qa-db-ja.com

OpenSSLシェルコマンドを使用してJSON Webトークン(JWT)を作成する方法

MacOS上のコマンドラインユーティリティを使用してJSON Webトークン(JWT)を作成し、署名部分を使用してスナッグを押しています。

私はこのgistに大いに触発されました: https://gist.github.com/drayam/dd47bf6eef849a57c07016c0036f5207

私のjwtのために私はヘッダーを持っています:

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

ペイロード:

{"email":"[email protected]"}
 _

そして私のHMACの秘密は次のとおりです。

bigsecretisveryhardtoguessbysneakypeopleright
 _

またはBase64では:

Ymlnc2VjcmV0aXN2ZXJ5aGFyZHRvZ3Vlc3NieXNuZWFreXBlb3BsZXJpZ2h0Cg==
 _

私は次のサイトを検証するために使用していました: https://jwt.io/

Base64バージョンのマイシークレットを使用してサイトにそのすべてを入力した場合、テストしているサイトに対して正常に検証された次のJWTを生成します。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImpvcmRhbkBleGFtcGxlLmNvbSJ9.C3MVjfmnul8dLNIgiv6Dt3jSefD07Y0QtDrOZ5oYSXo
 _

Bashでは私はこれを試してみました:

jwt_header=$(echo -n '{"alg":"HS256","typ":"JWT"}' | base64 | sed s/\+/-/g | sed 's/\//_/g' | sed -E s/=+$//)

payload=$(echo -n '{"email":"[email protected]"}' | base64 | sed s/\+/-/g |sed 's/\//_/g' |  sed -E s/=+$//)

hmac_signature=$(echo -n "${jwt_header}.${payload}" | openssl dgst -sha256 -hmac "${key}" -binary | openssl base64 -e -A | sed s/\+/-/g | sed 's/\//_/g' | sed -E s/=+$//)

jwt="${jwt_header}.${payload}.${hmac_signature}"
 _

これは次のものを作成しました。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImpyZWVkQGV4dG9sZS5jb20ifQ.o426f0XDnsUwActVt14Cr3X3IUqPwfv6yaN5nRaZhew
 _

私が投稿しているサイトで有効なものは受け入れられません。だから私は私が有効なHS256署名を得ていないopensslコマンドで間違っていることを理解していません。

9
Jordan Reed

私はからのJWTを再作成することができました https://jwt.io/

あなたの例では、ユーザーの秘密に隠された改行がありました。そのため、以下では、その改行でも、純粋に希望の出力を再現します。また、ペイロードの電子メールアドレスは一貫していませんでしたので、以下の場合は[email protected]を使用しました。

私はHMACステップへのわずかに異なるアプローチを取りました。ユーザーシークレットを16進数バイトに変換し、キーとして(HMACのhexkeyオプションを使用して)使用しました。

# Construct the header
jwt_header=$(echo -n '{"alg":"HS256","typ":"JWT"}' | base64 | sed s/\+/-/g | sed 's/\//_/g' | sed -E s/=+$//)

# ans: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

# Construct the payload
payload=$(echo -n '{"email":"[email protected]"}' | base64 | sed s/\+/-/g |sed 's/\//_/g' |  sed -E s/=+$//)

# ans: eyJlbWFpbCI6ImpvcmRhbkBleGFtcGxlLmNvbSJ9

# Store the raw user secret (with example of newline at end)
secret=$'bigsecretisveryhardtoguessbysneakypeopleright\n'

# Note, because the secret may have newline, need to reference using form $"" 
echo -n "$secret"

# Convert secret to hex (not base64)
hexsecret=$(echo -n "$secret" | xxd -p | paste -sd "")

# ans: 62696773656372657469737665727968617264746f67756573736279736e65616b7970656f706c6572696768740a

# For debug, also display secret in base64 (for input into https://jwt.io/)
echo -n "$secret" | base64

# ans: Ymlnc2VjcmV0aXN2ZXJ5aGFyZHRvZ3Vlc3NieXNuZWFreXBlb3BsZXJpZ2h0Cg==

# Calculate hmac signature -- note option to pass in the key as hex bytes
hmac_signature=$(echo -n "${jwt_header}.${payload}" |  openssl dgst -sha256 -mac HMAC -macopt hexkey:$hexsecret -binary | base64  | sed s/\+/-/g | sed 's/\//_/g' | sed -E s/=+$//)

# Create the full token
jwt="${jwt_header}.${payload}.${hmac_signature}"

# ans: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImpvcmRhbkBleGFtcGxlLmNvbSJ9.C3MVjfmnul8dLNIgiv6Dt3jSefD07Y0QtDrOZ5oYSXo
2
Darren Smith