【问题标题】:Create RS256 JWT in bash在 bash 中创建 RS256 JWT
【发布时间】:2019-10-09 22:30:59
【问题描述】:

我正在尝试仅使用 bash 和 openSSL 构建一个 RS256 JWT 令牌(我可以使用的开发工具有限)。

我设计了一个脚本,它从 txt 文件中获取标头和有效负载(去除换行符等),base-64URL 对它们进行编码并将它们与 '.' 连接在一起。分隔符。

然后我尝试对输出进行签名,我还对其进行了 base-64URL 编码并附加到末尾(使用另一个“.”分隔符)。我相信这准确地反映了 JWT 模型。

我的私钥和证书是使用 openSSL 生成的:

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout ./privateKey2.key -out ./certificate2.crt

我的公钥是从私钥生成的:

openssl rsa  -pubout -in ./privateKey2.key > ./publicKey2.key

然后我有以下处理该作业的 bash 脚本:

cat header.txt | tr -d '\n' | tr -d '\r' | openssl base64 | tr +/ -_ | tr -d '=' > header.b64
cat payload.txt | tr -d '\n' | tr -d '\r' | openssl base64 | tr +/ -_ |tr -d '=' > payload.b64
printf "%s" "$(<header.b64)" "." "$(<payload.b64)" > unsigned.b64
rm header.b64
rm payload.b64
openssl rsautl -sign -inkey privateKey2.key -in unsigned.b64 -out sig.txt
cat sig.txt | openssl base64 | tr +/ -_ | tr -d '=' > sig.b64
printf "%s" "$(<unsigned.b64)" "." "$(<sig.b64)" > jwt.txt
rm unsigned.b64
rm sig.b64
rm sig.txt

我相信脚本本身可以工作,但是每当我将最终输出上传到 jwt.io 的测试工具时,它都会告诉我签名无效(它可以读取内容并且标头和有效负载是正确的)。

我对 openssl rsautl 的使用不正确吗?

如果他们有帮助,很高兴包含键/示例数据

示例输出:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2
MjM5MDIyfQ.fE-btiyskyDrO1mQXcICP0udbCkdV9D_50CYNbpRVgod6EPjKmbOJK-EA7vn7s5l
TtkvKw0m1r45poGApBT4SA_ChmEgsPzhGwxd2xpInesRon-mWTzsUqqz0C1CcegT
n9Z19JzGJ7wUjomg7viKI1OP7Ei6TptINE8hPqEBPPpeO2PfT5IevMb1XytaCuTO
R1JMurgwsIa0Kq3LaFoAk1stUnTtJRI8-NHzWqmUiQpq-K1eteBtT9ZvKXJ_6ReY
_AetoeqmEDVQO_UV2ae_dKd4QHSV8D-ryJFc-OEYWzgwGeqXSBMNVMzsXKSUIR8C
sfvZ2hvwbQI2f0J6gZQw0w

对应的公钥

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1YbvZ3CPPr3X47J/pqCD
ciE0AhRbiBrybu4T3GbbHfGYROaPSKx2LfXCwAlayln5zNaZ14cvlDHEpCIQviPk
Qv5Ux16R2QouhF0ZugyMHLQkusVXG6Va14eFVKkcO2g1c25bOMAk4V3vSsVnMMQS
fTPunpGVrBUBo2We5P+cKldBNXKBlXEAIRGc4/fTcTB4F8opP+x5ACIZ04SWKafJ
MSvujIfpBxs476bvxA5xlPQiOhbOIo/bhPMJI6AlaDTJ03pGTOYjR5jZlB03j4YD
EF/2hhidvvFnLHdPkewzDsn0aZi+fqBNvQhS0hutnvp6F8hGL9e5hh8G7a2AXy9F
2QIDAQAB
-----END PUBLIC KEY-----

【问题讨论】:

  • 你能举出你的 header.txt 和 payload.txt 文件的例子吗?

标签: bash macos openssl jwt


【解决方案1】:

我将David Fulton's Answer 与documentation from github 以及一些jwt-with-bash 和rsa-sign-and-verify 链接组合在一起。

由于尾​​随换行符(我认为),重构 base64-ification 很棘手。相反,只需将所有命令保持内联即可。

PEM=$( cat my/pem/file )
GITHUB_APP_ID=4 # Whatever your github app id is

NOW=$( date +%s )
IAT="${NOW}"
# expire 9 minutes in the future. 10 minutes is the max for github
EXP=$((${NOW} + 540))
HEADER_RAW='{"alg":"RS256"}'
HEADER=$( echo -n "${HEADER_RAW}" | openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n' )
PAYLOAD_RAW='{"iat":'"${IAT}"',"exp":'"${EXP}"',"iss":'"${GITHUB_APP_ID}"'}'
PAYLOAD=$( echo -n "${PAYLOAD_RAW}" | openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n' )
HEADER_PAYLOAD="${HEADER}"."${PAYLOAD}"
SIGNATURE=$( openssl dgst -sha256 -sign <(echo -n "${PEM}") <(echo -n "${HEADER_PAYLOAD}") | openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n' )
JWT="${HEADER_PAYLOAD}"."${SIGNATURE}"

#${JWT} now has our token

【讨论】:

  • 这看起来很有希望,可以使用 json 文件代替 PEM 文件吗?还是将私钥作为字符串更好?
  • 我不知道任何接受json文件的私钥格式,也不知道你所说的“私钥作为字符串”是什么意思。
  • 顺便说一句——全大写变量名称由 POSIX 规范定义,用于反映或修改 POSIX 指定实用程序行为的变量,而小写名称保留供应用程序使用并保证不会对外壳本身产生意外影响。请参阅 pubs.opengroup.org/onlinepubs/9699919799/basedefs/… 制定此约定。
【解决方案2】:

成功解决了这个问题。这是由几个问题引起的:

  1. openssl base64 默认每 70 多个字符插入回车。我相信您可以覆盖它,但只需使用 base64 命令即可解决此问题。
  2. 我的签名步骤错误。我将rsautl替换为dgst如下:

    openssl dgst -sha256 -sign private.key -out sig.txt unsigned.b64

RS256 签名现在可以在 jwt.io 中通过验证

完整的工作代码(供后代使用):

cat header.txt | tr -d '\n' | tr -d '\r' | base64 | tr +/ -_ | tr -d '=' > header.b64
cat payload.txt | tr -d '\n' | tr -d '\r' | base64 | tr +/ -_ |tr -d '=' > payload.b64
printf "%s" "$(<header.b64)" "." "$(<payload.b64)" > unsigned.b64
rm header.b64
rm payload.b64
openssl dgst -sha256 -sign -privateKey2.key -out sig.txt unsigned.b64
cat sig.txt | base64 | tr +/ -_ | tr -d '=' > sig.b64
printf "%s" "$(<unsigned.b64)" "." "$(<sig.b64)" > jwt.txt
rm unsigned.b64
rm sig.b64
rm sig.txt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-01
    • 2020-03-29
    • 2020-04-18
    • 2018-02-03
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 2020-04-25
    相关资源
    最近更新 更多