madaster97 / openssl-jws

3 stars 0 forks source link

ASN.1 Integers may be too short #1

Open nischu opened 1 year ago

nischu commented 1 year ago

I am creating ES256 JWT tokens using shell scripts and OpenSSL and noticed that sometimes, the generated signatures are invalid. Ultimately, the integers asn1parse delivers may be too short, I fixed that by zero-padding the hexadecimal integers before concatenating them:

printf '%s' "${input}" | openssl dgst -sha256 -sign Private.p8 | openssl asn1parse -inform DER | perl -n -e'/INTEGER           :([0-9A-Z]*)$/ && printf "%064s", $1' | xxd -p -r

I created thousands of signatures and all are now valid according to my validation script:

        JWT="..."
    IFS='.' read -r -a 'JWT_COMPONENTS' <<< "$JWT"
    HEADER="${JWT_COMPONENTS[0]}"
    PAYLOAD="${JWT_COMPONENTS[1]}"
    SIGNATURE="${JWT_COMPONENTS[2]}"
    DATA="${HEADER}.${PAYLOAD}"

    RS_PACKED="$(printf '%s' "${SIGNATURE}" | basenc --base64url -d 2>/dev/null | xxd -p -c 64)"
    R="${RS_PACKED:0:64}"
    S="${RS_PACKED:64:64}"

    ASN_DESC=$(mktemp)
    DER=$(mktemp)
    printf '%s' "${SIGNATURE}" | basenc --base64url -d 2>/dev/null > "$SIG"

    cat << EOF > "$ASN_DESC"
asn1 = SEQUENCE:integers

[integers]
r=INTEGER:0x$R
s=INTEGER:0x$S
EOF

    openssl asn1parse -genconf "$ASN_DESC" -out "$DER" >/dev/null 2>/dev/null
    rm "$ASN_DESC"

    printf '%s' "${DATA}" | openssl dgst -sha256 -verify Public.p8 -signature "$DER"
    rm "$DER"
nickpl456 commented 9 months ago

Thank you for the fix, it works great!