如何使用bash / shell脚本创建RS256 JWT断言?

时间:2017-10-10 00:41:01

标签: linux bash shell jwt

我试图设置一个shell脚本来从Box帐户中获取文件。为此,需要一个身份验证令牌。必须通过脚本自动生成身份验证令牌,因此无需手动执行步骤。这可以通过构建和提交JWT索赔来完成。

Box的文档指定它们只接受“RS256”,“RS384”和“RS512”。我已经能够设置我需要的一切,除了使用Box的文档和本网站创建断言:

http://willhaley.com/blog/generate-jwt-with-bash/

我花了好几个小时搜索网站,看看我是否能找到关于如何使用bash / shell脚本生成断言的任何指示都无济于事。我链接的网站是我发现的最接近的网站,但它使用的是HS256,Box不支持。

我的脚本目前几乎与我之前链接的网站上的第一个脚本相同(我有一个单独的脚本,我用来测试实际使用手动生成的身份验证令牌抓取文件)。请帮助生成断言所需的命令。

1 个答案:

答案 0 :(得分:9)

考虑以下内容,它支持HS256和RS256:

container_2

...用法:

#!/usr/bin/env bash

# Inspired by implementation by Will Haley at:
#   http://willhaley.com/blog/generate-jwt-with-bash/

set -o pipefail

# Shared content to use as template
header_template='{
    "typ": "JWT",
    "kid": "0001",
    "iss": "https://stackoverflow.com/questions/46657001/how-do-you-create-an-rs256-jwt-assertion-with-bash-shell-scripting"
}'

build_header() {
        jq -c \
                --arg iat_str "$(date +%s)" \
                --arg alg "${1:-HS256}" \
        '
        ($iat_str | tonumber) as $iat
        | .alg = $alg
        | .iat = $iat
        | .exp = ($iat + 1)
        ' <<<"$header_template" | tr -d '\n'
}

b64enc() { openssl enc -base64 -A | tr '+/' '-_' | tr -d '='; }
json() { jq -c . | LC_CTYPE=C tr -d '\n'; }
hs_sign() { openssl dgst -binary -sha"${1}" -hmac "$2"; }
rs_sign() { openssl dgst -binary -sha"${1}" -sign <(printf '%s\n' "$2"); }

sign() {
        local algo payload header sig secret=$3
        algo=${1:-RS256}; algo=${algo^^}
        header=$(build_header "$algo") || return
        payload=${2:-$test_payload}
        signed_content="$(json <<<"$header" | b64enc).$(json <<<"$payload" | b64enc)"
        case $algo in
                HS*) sig=$(printf %s "$signed_content" | hs_sign "${algo#HS}" "$secret" | b64enc) ;;
                RS*) sig=$(printf %s "$signed_content" | rs_sign "${algo#RS}" "$secret" | b64enc) ;;
                *) echo "Unknown algorithm" >&2; return 1 ;;
        esac
        printf '%s.%s\n' "${signed_content}" "${sig}"
}

(( $# )) && sign "$@"