当前位置: 首页 > 知识库问答 >
问题:

在bash中创建RS256 JWT

闻人望
2023-03-14

我试图仅使用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-----

共有2个答案

薛泰
2023-03-14

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

>

  • 默认情况下,openssl base64 inserts回车每70个字符返回一次。我相信您可以覆盖这个,但只需使用base64命令即可解决这个问题
  • 我的签名步骤错误。我将rsautl替换为dgst,如下所示:

    OpenSL dgst-sha256private.keysig.txtunsigned. 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
    

  • 尹辰沛
    2023-03-14

    我将David Fulton的答案与github的留档以及一些jwt-with-bash和rsa-sign-and-验证链接相结合。

    重构base 64化很棘手,因为拖尾换行符(我认为)。相反,只需将所有命令保持内联即可。

    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
    
     类似资料:
    • 问题内容: 有客观的更好的方法在bash脚本中创建临时文件吗? 我通常只要给他们起名就可以使用它们,例如tempfile-123,因为脚本结束后它将被删除。除了覆盖当前文件夹中可能的tempfile-123之外,这样做是否有其他缺点?还是以更谨慎的方式创建临时文件有什么好处? 问题答案: 该手册页解释了它相当好: 传统上,许多shell脚本使用pid作为后缀来命名程序名称,并将其用作临时文件名。这

    • 我试图在shell脚本中创建一个时间戳变量,以使日志记录更加容易。我希望在脚本的开头创建变量,并让它在发出时打印出当前时间。事实证明,这比我想象的要困难得多。以下是我尝试过的一些事情: 我尝试过的其他东西只是轻微的变化,没有更好的效果。有人知道如何完成我想做的事吗?

    • 问题内容: 在系统调用中,如果使用打开,系统调用将确保仅在文件不存在时才创建该文件。系统调用保证原子性。有没有类似的方法可以通过bash脚本以原子方式创建文件? 更新:我发现了两种不同的原子方式 使用set -o noclobber。然后,您可以原子地使用>运算符。 只需使用mkdir。Mkdir是原子的 问题答案: 100%纯bash解决方案: 如果不存在名为的文件,则此命令将创建一个名为的文件

    • 我正在使用Python和Pandas编写多个bash脚本。我有一只熊猫。包含脚本的系列。简化:: 然后我使用创建文件。输出文件如下所示: 我已经尝试了这里的所有建议Python-在引号中使用引号(三重引号,单引号和双引号(如示例所示),转义引号),以及使引用的文本成为变量,但都不起作用。

    • 问题内容: 我在Debian GNU / Linux 6.0上使用Bash。是否可以获取文件创建日期/时间?不是修改日期/时间。 和两个只给出修改时间。 问题答案: 不幸的是,您的搜寻通常无法进行,因为POSIX标准定义了每个文件仅存储3个不同的时间值(请参见基本定义部分4.8文件时间更新)。 每个文件具有三个不同的关联时间戳:上次数据访问的时间,上次数据修改的时间以及文件状态上次更改的时间。这些

    • 本文向大家介绍在Bash脚本中创建和使用数组方法总结,包括了在Bash脚本中创建和使用数组方法总结的使用技巧和注意事项,需要的朋友参考一下 在Bash中定义一个数组 有两种方法可以在bash脚本中创建新数组。第一个是使用declare命令来定义一个Array。此命令将定义名为test_array的关联数组。 $ declare -a test_array 还可以通过分配元素来创建数组。 $ tes