[英]Why is my OpenSSL-generated signature different than the signature from PyCryptodome?
[英]Why openssl generated signature looks different than pyjwt generated signature
我正在嘗試驗證使用 PyJWT 創建的 JWT 簽名,但它失敗了。 如果使用 openssl 命令創建簽名,則它可以工作。
我有兩個腳本。
Python 腳本,它使用 PyJWT 和 PyOpenSSL 創建 JWT。 如果成功,它會在標准輸出上吐出 JWT。
執行兩個實驗的 Bash 腳本。
實驗一成功,二失敗。
我對類似問題的回答很少,並試圖確保
使用 openssl 命令生成的簽名驗證成功。 使用 PyJWT 生成的簽名無法通過 openssl 驗證。 使用 PyJWT 創建的 JWT 使用 PyJWT 成功解碼。
我已經沒有關於調試這個的想法了。 任何幫助,方向都非常感謝。
jwttest.py(需要 PyJwt、PyOpenSSL)
import sys
import base64
import jwt
'''
# Just in case keys are not available
privkey="-----BEGIN PRIVATE KEY-----\n" \
"MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQC8JuSavoT2vyZi\n" \
"2RsQ0BFBySQVbK2JJPXXi1O33D3JZhUjQhyRh4yaG6ubirdM/r0eZeADdD047T8i\n" \
"wXFxH/dCZun7AF1dBcXxx1/Jr1VsNiaymXPrnRUBSrCSjqNEJIEbRiKna/JY8i6q\n" \
"cXZRTOYead8fXrTIWJRUTx5F4MNAXqdZ5v/oAsxXc1E7il55vOBDgKZSW4rV7SRC\n" \
"W4zqQA/PE9FmkrygV2x4Kbzc3aObgjgMYR99o6vyOkIhqycBPivwvyLgymDah07r\n" \
"1OR/u2z2w1zX5wD9NyLx2wqbpFQypDr0bOW4CsXuHcPEo206g//6EYlkGOW16ZZr\n" \
"Rhv9t8ipAgMBAAECgf92U/9xUmBMzepWQDPFXxV7SgRndPGuTpBN/lGoT9qLzqd8\n" \
"hRdybsz+HmjOaW7d/Vbyxx8bDP9zzcDnGsE9Y90c5ZxBPvl4hyj15W1YaexPIb80\n" \
"k01T4HZVWaOyiAIl2M9ZV8JziG/hgG3Yw4KlnrcaaXrpP6ZyWULvwtJHIBOrZsei\n" \
"CIlF/cmmwS1uHmXLGTUmZyusOeMfhcQFIh1p3r6dw9Dt6r022FvuMWrqxfsdEAP0\n" \
"kCfhuyyczPIX50gMnVN07ApqH/aMh+77fa8z6pEhqqQeQTkM6ttVzz8l9bEdaHyd\n" \
"T3IXI0G2BfuokGKLAWEKCTFfJbEODDSaSacua9UCgYEA4x+POFom84xJhqgvQdAL\n" \
"ZbDjNadRA6avJ2lDz6PhPSAzq6lleyUj7wv6p1O+37MriPKqkwMXWfZuPXaYEApv\n" \
"VQRxNCofeLjYoueWRAxIts6//1L3ueW1KmQBqGAC5oq3+vy372EvIubmzAmr5hcb\n" \
"3jmzCBjsWzTS/z3s2DpVa78CgYEA1BLjb5zrpnrMP/JJ5SaE9JzGRZ2wmB6wph83\n" \
"U3YYm9j/Qtih24I48EON7zLz/utzGZstoHEwAe8d0F1mxFslsj0A0Y6nIE1rH0Za\n" \
"MAsjkxlU0e+iaZZ9WSVvg7D3i7+dYVKpvHW7SKKYcqvJWNs7u+qkGUqiGuDoEJPr\n" \
"JM5lhZcCgYBlFXa4recIHjfbJp9huyZXbBKznnQAG/94mvEDSPzGJ77Xd90iobUM\n" \
"f1hfgHZDOYr2uIoSRB3wfC00TcP/36UNQZzgip7XK+2/EzNdtdnnAr2Q9Wwr4IBx\n" \
"DXFvbsvbr4GSw0dZ0vcXoYy24tcO4NoWXbfAstb/ANOnpffzhILgIQKBgAw43nSz\n" \
"RX19vEG/M/UJ6EW0t1SRxvitZB7e07BysO5ibiurEoD1G1T1f7uWYyuA5ExIfjOt\n" \
"8kdaQYydpWuRmTWRgHeTUhxxecf+pPn52l4C6rmCpwiQzL6Tgr7DNzENpQNT4UZk\n" \
"PpvsCv8o2VzOnb2xwy1V+Mu1xIoYDEg9wOoXAoGBAN8jWNrtxMQCgCdjwc5gOgs5\n" \
"fRdGVa2yly4dXCzVJl6DN3sEmIOuIZfMXeSNuA40AR6qT36F72WcCVE63ZzKvqtX\n" \
"WPjy/jPyQ9pp1dBKKRQCtktt7Iovuqfkc/XtGg1vv5PCefR4f2GKPCvCL3mPKOEB\n" \
"QWCwIEiwAse5z50XfN10\n" \
"-----END PRIVATE KEY-----\n"
pubkey = "-----BEGIN PUBLIC KEY-----\n" \
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvCbkmr6E9r8mYtkbENAR\n" \
"QckkFWytiST114tTt9w9yWYVI0IckYeMmhurm4q3TP69HmXgA3Q9OO0/IsFxcR/3\n" \
"Qmbp+wBdXQXF8cdfya9VbDYmsplz650VAUqwko6jRCSBG0Yip2vyWPIuqnF2UUzm\n" \
"HmnfH160yFiUVE8eReDDQF6nWeb/6ALMV3NRO4peebzgQ4CmUluK1e0kQluM6kAP\n" \
"zxPRZpK8oFdseCm83N2jm4I4DGEffaOr8jpCIasnAT4r8L8i4Mpg2odO69Tkf7ts\n" \
"9sNc1+cA/Tci8dsKm6RUMqQ69GzluArF7h3DxKNtOoP/+hGJZBjltemWa0Yb/bfI\n" \
"qQIDAQAB\n" \
"-----END PUBLIC KEY-----\n"
'''
data={}
'''
data=
{
"iss": "http://localhost:8080/uaa/oauth/token",
"user_name": "DBA",
"nbf": 1592397960,
"exp": 1621295999
}
'''
def padstr(str):
padding = len(str) % 4
if padding:
data = str
data += '=' * (4 - padding)
return data
return str
if len(sys.argv) < 3 :
print "Usage: " + sys.argv[0] + " <private key file>" + " <public key file>"
exit(1)
with open(sys.argv[1], "r") as f:
privkey=f.read()
#print privkey
with open(sys.argv[2], "r") as f:
pubkey=f.read()
#print pubkey
encoded=jwt.encode(data, privkey, algorithm="RS256")
decoded=jwt.decode(encoded, pubkey, algorithms="RS256")
if( decoded != data ):
print "decoded JWT does not match data"
print "Data=" + str(data)
print "Decoded=" + decoded
exit(1)
else:
print encoded
exit(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
解決。 愚蠢的錯誤。 我假設驗證簽名的消息是“header.payload”。 它是'b64_urlsafe(header).b64_urlsafe(payload)'。 我重新閱讀了我所指的 JWT 文章,他們確實指出了這一點。 很抱歉浪費了您的帶寬。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.