如何使用OpenSSL Shell命令创建Json Web令牌(JWT)? [英] How to create a Json Web Token (JWT) using OpenSSL shell commands?
问题描述
我正在尝试在MacOS上使用命令行实用程序创建JSON Web令牌(JWT),并在签名部分遇到麻烦.
I'm trying to create a JSON Web Token (JWT) using command line utilities on MacOS and hitting a snag with the signing portion.
这个要点给我很大的启发: https://gist.github.com/indrayam/dd47bf6eef849a57c07016c0036f5207
I was greatly inspired by this gist: https://gist.github.com/indrayam/dd47bf6eef849a57c07016c0036f5207
对于我的JWT,我有 标题:
For my JWT I have Header:
{"alg":"HS256","typ":"JWT"}
有效载荷:
{"email":"jordan@example.com"}
我的hmac秘诀是:
bigsecretisveryhardtoguessbysneakypeopleright
或者在base64中:
Or in base64:
Ymlnc2VjcmV0aXN2ZXJ5aGFyZHRvZ3Vlc3NieXNuZWFreXBlb3BsZXJpZ2h0Cg==
我正在使用以下网站进行验证: https://jwt.io/
I was using the following site to validate: https://jwt.io/
我发现,如果我使用我的密码的base64版本将所有内容输入该站点,它将生成以下JWT,该JWT已针对我正在测试的站点成功进行了验证:
I find that if I enter all of that into the site using the base64 version of my secret, it generates the following JWT that successfully verifies against the site I'm testing:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImpvcmRhbkBleGFtcGxlLmNvbSJ9.C3MVjfmnul8dLNIgiv6Dt3jSefD07Y0QtDrOZ5oYSXo
在bash中,我尝试了以下方法:
In bash I tried this with:
jwt_header=$(echo -n '{"alg":"HS256","typ":"JWT"}' | base64 | sed s/\+/-/g | sed 's/\//_/g' | sed -E s/=+$//)
payload=$(echo -n '{"email":"jordan@example.com"}' | 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
我要发布到的网站不接受其中的哪个为有效.因此,我不确定在openssl命令中我做错了什么,而该命令没有获得有效的HS256签名.
Which is not accepted as valid by the site I'm posting to. So I'm unsure what I am doing wrong in the openssl command that is not getting a valid HS256 signature.
推荐答案
在您的示例中,用户密码上有一个隐藏的换行符.因此,在下面,我还添加了该换行符,纯粹是为了重新创建所需的输出.
另外,您有效负载中的电子邮件地址不一致,因此下面我使用了jordan@example.com
.
In your example, there was a hidden newline on the user secret. So in the below, I also add on that newline, purely to recreate the desired output.
Also the email address in your payload was not consistent, so for below I have used jordan@example.com
.
我对hmac步骤采取了略有不同的方法.我将用户密码转换为十六进制字节,并将其用作密钥(对HMAC使用hexkey
选项).
I took a slightly different approach to the hmac step. I converted the user secret to hex bytes and used that as the key (using the hexkey
option for the HMAC).
# 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":"jordan@example.com"}' | 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
这篇关于如何使用OpenSSL Shell命令创建Json Web令牌(JWT)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!