为什么openssl生成的签名与pyjwt生成的签名看起来不同

为什么openssl生成的签名与pyjwt生成的签名看起来不同,openssl,jwt,Openssl,Jwt,我试图验证使用PyJWT创建的JWT签名,但失败了。如果签名是使用openssl命令创建的,那么它就可以工作 我有两个脚本 使用PyJWT和PyOpenSSL创建JWT的Python脚本。如果成功,它会在stdout上抛出JWT Bash脚本,它执行两个实验 运行Python脚本并捕获JWT。解码报头、有效负载部分。构造要签名的消息。使用openssl命令创建签名(使用dgst),使用公钥验证 从JWT中,解码heder、有效载荷和签名部分。使用openssl命令验证JWT使用公钥创建的签名

我试图验证使用PyJWT创建的JWT签名,但失败了。如果签名是使用openssl命令创建的,那么它就可以工作

我有两个脚本

使用PyJWT和PyOpenSSL创建JWT的Python脚本。如果成功,它会在stdout上抛出JWT

Bash脚本,它执行两个实验

  • 运行Python脚本并捕获JWT。解码报头、有效负载部分。构造要签名的消息。使用openssl命令创建签名(使用dgst),使用公钥验证
  • 从JWT中,解码heder、有效载荷和签名部分。使用openssl命令验证JWT使用公钥创建的签名
实验一成功,实验二失败

对于类似的问题,我已经给出了一些答案,并试图确保

  • 我使用urlsafe b64编码
  • 我使用openssldgst命令创建输入消息的散列,该消息经过签名
  • 移动数据时使用echo-n
使用openssl命令生成的签名验证成功。 使用PyJWT生成的签名无法通过openssl验证。 使用PyJWT创建的JWT使用PyJWT成功解码

我已经没有办法调试这个了。 非常感谢您的帮助和指导

jwttest.py(需要PyJwt、PyOpenSSL)

导入系统 导入base64 进口jwt ''' #以防万一钥匙不可用 privkey=“----开始私钥------\n”\ “miieuwibadanbgkqhkig9w0baqefaascbkuwggshageaoibaqc8jusavot2vyzi\n”\ “2RSQ0BFBYQVBK2JJPXXI1O33D3JZUJQHYRH4YAG6UBIRDM/r0eZeADdD047T8i\n”\ “wXFxH/dCZun7AF1dBcXxx1/Jr1VsNiaymXPrnRUBSrCSjqNEJIEbRiKna/JY8i6q\n”\ “CXZRTOYAD8FXRTIWJRUTX5F4MNAXQDZ5V/oAsxXc1E7il55vOBDgKZSW4rV7SRC\n”\ “W4zqQA/PE9FMKRYGV2x4KBZC3AOBGMYR99O6VYOKIHQYCBPIVVYLGYMDAH07R\n”\ “1OR/u2z2w1zX5wD9NyLx2wqbpFQypDr0bOW4CsXuHcPEo206g//6EYlkGOW16ZZr\n”\ “Rhv9t8ipAgMBAAECgf92U/9XUMBMZEPWQDPFFXXV7SGRNDPGUTPBN/lGoT9qLzqd8\n”\ “hRdybsz+HmjOaW7d/VBYX8BDP9ZZCDNGSE9Y90C5ZXBPVL4HYJ15W1YAEXPIB80\n”\ “K01T4HZVWAOYIAIL2M9ZV8JZG/HGG3YW4KLNRCAXP6ZYWULWWTJHIBORZSEI\n”\ “CIlF/CMMWS1UHMXLGTUMZYUSOEMFHCQFIH1P3R6DW9DT6R022VUMWRQXFSDEAP0\n”\ “KCFHUYCZPIX50GMNVN07APQH/aMh+77FA8Z6PEHQQQEQTKM6TVZZ8L9BEDAHYD\n”\ “T3IXI0G2BfuokklawekCtfjbeoddsasacua9ucgyea4x+POFom84xJhqgvQdAL\n”\ “ZbDjNadRA6avJ2lDz6PhPSAzq6lleyUj7wv6p1O+37MriPKqkwMXWfZuPXaYEApv\n”\ “VQRxNCofeLjYoueWRAxIts6//1L3ueW1KmQBqGAC5oq3+vy372EvIubmzAmr5hcb\n”\ “3jmzCBjsWzTS/z3s2DpVa78CgYEA1BLjb5zrpnrMP/JJ5SaE9JzGRZ2wmB6wph83\n”\ “U3YYm9j/Qtih24I48EON7zLz/utzGZstoHEwAe8d0F1mxFslsj0A0Y6nIE1rH0Za\n”\ “MAsjkxlU0e+iaZZ9WSVvg7D3i7+dYVKpvHW7SKKYcqvJWNs7u+qkGUqiGuDoEJPr\n”\ “JM5LHZCGYBLFxa4ReciHJFBJP9HuyzxBKZNNQAG/94mvEDSPzGJ77Xd90iobUM\n”\ “f1hfgHZDOYr2uIoSRB3wfC00TcP/36UNQZzgip7XK+2/EzNdtdnnAr2Q9Wwr4IBx\n”\ “DXFVBVBR4GSW0DZ0VCXOYY24TCO4NOWXBFASTB/ANONPFZHILGIQKBGAW43NSZ\n”\ “RX19vEG/M/UJ6EW0t1SRxvitZB7e07BysO5ibiurEoD1G1T1f7uWYyuA5ExIfjOt\n”\ “8kdaQYydpWuRmTWRgHeTUhxxecf+PPN52L4C6RMCPWIQZL6TGR7DNZENPCNT4UZK\n”\ “PpvsCv8o2VzOnb2xwy1V+Mu1xIoYDEg9wOoXAoGBAN8jWNrtxMQCgCdjwc5gOgs5\n”\ “fRdGVa2yly4dXCzVJl6DN3sEmIOuIZfMXeSNuA40AR6qT36F72WcCVE63ZzKvqtX\n”\ “WPjy/JPYQ9PP1DBKRQCTKTT7IOVUQFKC/XTGG1VV5PCEFR4F2GKPCCL3MPKOEB\n”\ “QWCwIEiwAse5z50XfN10\n”\ “----结束私钥------\n” pubkey=“----开始公钥------\n”\ “miibijanbgkqhkig9w0baqefaocaq8amiibcgkcaqeavcmr6e9r8mytkbenar\n”\ “QckkFWytiST114tTt9w9yWYVI0IckYeMmhurm4q3TP69HmXgA3Q9OO0/IsFxcR/3\n”\ “Qmbp+WBDXQXF8CDFYA9VBDYMSPLZ650VAUQWKO6JRCSBG0YIP2VYWPIUQNF2UUUZM\n”\ “HMNFH160YFIUVE8EREDQF6NWEB/6ALMV3NRO4PEEBZGQ4CMULK1E0KQLUM6KAP\n”\ “ZXPRZPK8OFDSECM83N2JM4I4DGEFAAOR8JPCIASNAT4R8L8I4MPG2ODO69TKF7TS\n”\ “9sNc1+cA/TCI8DSKM6RUMQ69GZLUARF7H3DXKNTOOP/+hGJZBjltemWa0Yb/bfI\n”\ “qQIDAQAB\n”\ “----结束公钥------\n” ''' 数据={} ''' 资料= { “国际空间站”:http://localhost:8080/uaa/oauth/token", “用户名”:“DBA”, “nbf”:1592397960, “经验”:1621295999 } ''' def padstr(str): 填充=长度(str)%4 如果填充: 数据=str 数据+='='*(4-填充) 返回数据 返回str 如果len(sys.argv)<3: 打印“用法:”+sys.argv[0]+“+”“ 出口(1) 打开(sys.argv[1],“r”)作为f: privkey=f.read() #打印私钥 打开(sys.argv[2],“r”)作为f: pubkey=f.read() #打印公钥 encoded=jwt.encode(数据,privkey,algorithm=“RS256”) decoded=jwt.decode(编码,公钥,算法=“RS256”) 如果(已解码!=数据): 打印“解码的JWT与数据不匹配” 打印“数据=”+str(数据) 打印“已解码=”+已解码 出口(1) 其他: 打印编码 出口(0) sign_verification.sh

#!/bin/bash

function create_true_digest {
        data_file=$1
        digest_file=$2
        echo "Creating SHA256 digest for $data_file"
        ls -l $data_file
        cat $data_file
        echo
        openssl dgst -sha256 $data_file  | cut -d" " -f2 | xxd -r -p > $digest_file
        echo "digest stored in $digest_file"
        cat ${digest_file} | base64 -w 0 | sed 's/+/-/g' | sed 's/\//_/g' > ${digest_file}.base64
        echo "Base64 encoded digest stored in ${digest_file}.base64"
        ls -l ${digest_file}
        cat ${digest_file}.base64
        echo
        echo "............................................................"
}

function create_digest {
        create_true_digest $1 $2
}

function sign_data {
        data_file=$1
        pvtkey_file=$2
        signature_file=$3
        echo "Signing $data_file with $pvtkey_file"
        ls -l $data_file
        openssl dgst -sha256 -sign $pvtkey_file -out $signature_file $data_file
        #openssl dgst -sha256 -sign $pvtkey_file -binary -out $signature_file $data_file
        echo "Signature stored in $signature_file"
        cat $signature_file | base64 -w 0 | sed 's/+/-/g' | sed 's/\//_/g' > ${signature_file}.base64
        echo "Base64 encoded signature stored in ${signature_file}.base64"
        ls -l ${signature_file} ${signature_file}.base64
        echo "............................................................"
}

function verify_signature {
        signature_file=$1
        pubkey_file=$2
        data_file=$3
        echo "Verifying signature $signature_file with $pubkey_file against $data_file"
        openssl dgst -sha256 -verify $pubkey_file -signature $signature_file $data_file
        echo "............................................................"
}

function experiment_1 {
        echo "Experiment 1: This experiment accepts a message to verify"
        echo "  It uses openssl commands to generate a signature and verifies it"
        echo

        message_to_verify=$1
        #message_to_verify="{\"alg\":\"RS256\",\"typ\":\"JWT\"}.{}"
        pvtkey_file=$2
        pubkey_file=$3

        data_file="sign_data.txt"
        rm -f $data_file
        echo -n $message_to_verify > $data_file
        echo "Data stored in $data_file"

        digest_file="data_digest.bin"
        rm -f $digest_file
        rm -f ${digest_file}.base64
        create_digest $data_file $digest_file

        signature_file="signature_r.bin"
        rm -f $signature_file
        rm -f ${signature_file}.base64
        sign_data $data_file $pvtkey_file $signature_file

        verify_signature $signature_file $pubkey_file $data_file

        echo "............................................................"
}

function experiment_2 {
        echo "Experiment 2: This experiment accepts a message to verify and signature to verify against"
        echo "  It uses openssl commands to verify the signature against the message"
        message_to_verify=$1
        signature=$2 # keep it encoded
        pubkey_file=$3

        data_file="sign_data.txt"
        rm -f $data_file
        echo -n $message_to_verify > $data_file
        echo "Data stored in $data_file"
        cat $data_file
        echo

        signature_file="signature_r.bin"
        rm -f $signature_file
        rm -f ${signature_file}.base64
        echo -n $signature | sed 's/-/+/g' | sed 's/_/\//g' | base64 -di >$signature_file
        echo "Signature stored in $signature_file"
        cat $signature_file | base64 -w 0 | sed 's/+/-/g' | sed 's/\//_/g' > ${signature_file}.base64
        echo "Base64 encoded signature stored in ${signature_file}.base64"
        ls -l ${signature_file} ${signature_file}.base64

        verify_signature $signature_file $pubkey_file $data_file

        echo "............................................................"
}

if [ $# -lt 2 ]
then
        echo "Usage: $0 <private key file> <public key file>"
        exit
fi

pvtkey_file=$1
pubkey_file=$2

# Get Base64URL encoded JWT
# Need python 2.7, PyJWT, PyOpenSSL
JWT=`/usr/local/software/python/python2/bin/python jwttest.py $pvtkey_file $pubkey_file`

# Split parts
echo "Ignore base64 warnings..."
header=`echo -n $JWT | cut -d"." -f1 | sed 's/-/+/g' | sed 's/_/\//g' | base64 -di`
payload=`echo -n $JWT | cut -d"." -f2 | sed 's/-/+/g' | sed 's/_/\//g' | base64 -di`
signature=`echo -n $JWT | cut -d"." -f3` # decoding will be done by routines
message_to_verify="${header}.${payload}"

experiment_1 $message_to_verify $pvtkey_file $pubkey_file
experiment_2 $message_to_verify $signature $pubkey_file
#/bin/bash
函数create\u true\u digest{
数据文件=$1
摘要文件=$2
echo“为$data\u文件创建SHA256摘要”
ls-l$data\u文件
cat$data\u文件
回声
openssl dgst-sha256$data_文件| cut-d”“-f2 | xxd-r-p>$digest_文件
echo“摘要存储在$digest\u文件中”
cat${digest\u file}base64-w 0 | sed's/+/-/g'| sed's/\/\ug'>${digest\u file}.base64
echo“存储在${digest_file}.Base64中的Base64编码摘要”
ls-l${digest_file}
cat${digest_file}.base64
回声
回音“………………”
}
函数create_digest{
创建\u真实\u摘要$1$2
}
函数符号数据{
数据文件=$1
pvtkey_文件=$2
签名文件=$3
echo“使用$pvtkey\u文件对$data\u文件进行签名”
ls-l$data\u文件
openssl dgst-sha256-签名$pvtkey_文件-输出$signature_文件$data_文件
#openssl dgst-sha256-签名$pvtkey_文件-二进制-输出$signature_文件$data_文件
echo“存储在$Signature\u文件中的签名”
cat$signature\u file | base64-w 0 | sed's/+/-/g'| sed's/\/\ug'>${signature\u file}.base64
echo“Base64编码信号”
#!/bin/bash

function create_true_digest {
        data_file=$1
        digest_file=$2
        echo "Creating SHA256 digest for $data_file"
        ls -l $data_file
        cat $data_file
        echo
        openssl dgst -sha256 $data_file  | cut -d" " -f2 | xxd -r -p > $digest_file
        echo "digest stored in $digest_file"
        cat ${digest_file} | base64 -w 0 | sed 's/+/-/g' | sed 's/\//_/g' > ${digest_file}.base64
        echo "Base64 encoded digest stored in ${digest_file}.base64"
        ls -l ${digest_file}
        cat ${digest_file}.base64
        echo
        echo "............................................................"
}

function create_digest {
        create_true_digest $1 $2
}

function sign_data {
        data_file=$1
        pvtkey_file=$2
        signature_file=$3
        echo "Signing $data_file with $pvtkey_file"
        ls -l $data_file
        openssl dgst -sha256 -sign $pvtkey_file -out $signature_file $data_file
        #openssl dgst -sha256 -sign $pvtkey_file -binary -out $signature_file $data_file
        echo "Signature stored in $signature_file"
        cat $signature_file | base64 -w 0 | sed 's/+/-/g' | sed 's/\//_/g' > ${signature_file}.base64
        echo "Base64 encoded signature stored in ${signature_file}.base64"
        ls -l ${signature_file} ${signature_file}.base64
        echo "............................................................"
}

function verify_signature {
        signature_file=$1
        pubkey_file=$2
        data_file=$3
        echo "Verifying signature $signature_file with $pubkey_file against $data_file"
        openssl dgst -sha256 -verify $pubkey_file -signature $signature_file $data_file
        echo "............................................................"
}

function experiment_1 {
        echo "Experiment 1: This experiment accepts a message to verify"
        echo "  It uses openssl commands to generate a signature and verifies it"
        echo

        message_to_verify=$1
        #message_to_verify="{\"alg\":\"RS256\",\"typ\":\"JWT\"}.{}"
        pvtkey_file=$2
        pubkey_file=$3

        data_file="sign_data.txt"
        rm -f $data_file
        echo -n $message_to_verify > $data_file
        echo "Data stored in $data_file"

        digest_file="data_digest.bin"
        rm -f $digest_file
        rm -f ${digest_file}.base64
        create_digest $data_file $digest_file

        signature_file="signature_r.bin"
        rm -f $signature_file
        rm -f ${signature_file}.base64
        sign_data $data_file $pvtkey_file $signature_file

        verify_signature $signature_file $pubkey_file $data_file

        echo "............................................................"
}

function experiment_2 {
        echo "Experiment 2: This experiment accepts a message to verify and signature to verify against"
        echo "  It uses openssl commands to verify the signature against the message"
        message_to_verify=$1
        signature=$2 # keep it encoded
        pubkey_file=$3

        data_file="sign_data.txt"
        rm -f $data_file
        echo -n $message_to_verify > $data_file
        echo "Data stored in $data_file"
        cat $data_file
        echo

        signature_file="signature_r.bin"
        rm -f $signature_file
        rm -f ${signature_file}.base64
        echo -n $signature | sed 's/-/+/g' | sed 's/_/\//g' | base64 -di >$signature_file
        echo "Signature stored in $signature_file"
        cat $signature_file | base64 -w 0 | sed 's/+/-/g' | sed 's/\//_/g' > ${signature_file}.base64
        echo "Base64 encoded signature stored in ${signature_file}.base64"
        ls -l ${signature_file} ${signature_file}.base64

        verify_signature $signature_file $pubkey_file $data_file

        echo "............................................................"
}

if [ $# -lt 2 ]
then
        echo "Usage: $0 <private key file> <public key file>"
        exit
fi

pvtkey_file=$1
pubkey_file=$2

# Get Base64URL encoded JWT
# Need python 2.7, PyJWT, PyOpenSSL
JWT=`/usr/local/software/python/python2/bin/python jwttest.py $pvtkey_file $pubkey_file`

# Split parts
echo "Ignore base64 warnings..."
header=`echo -n $JWT | cut -d"." -f1 | sed 's/-/+/g' | sed 's/_/\//g' | base64 -di`
payload=`echo -n $JWT | cut -d"." -f2 | sed 's/-/+/g' | sed 's/_/\//g' | base64 -di`
signature=`echo -n $JWT | cut -d"." -f3` # decoding will be done by routines
message_to_verify="${header}.${payload}"

experiment_1 $message_to_verify $pvtkey_file $pubkey_file
experiment_2 $message_to_verify $signature $pubkey_file