I have 3 different scripts that should be basically identical logic wise, yet when run the RSA sig generated by python does not agree with the RSA sigs of the other two implementations. What am I doing differently in Python?
Ruby
#!/usr/bin/ruby
# ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]
require 'openssl'
require 'base64'
string_to_sign = """Method:GET
Hashed Path:rakSQTQa55Ls8KWcrShhane6uFY=
X-Ops-Content-Hash:O8Fciq4+QSTdQJA18y6i/Wg178k=
X-Ops-Timestamp:2023-05-18T15:26:59Z
X-Ops-UserId:test-user"""
puts "############################################################"
puts "Ruby"
puts "\nBase64 Encoding"
puts Base64.encode64(string_to_sign) # Adds newline every 60 bytes?
puts "\nsha1 Hash"
puts ::Base64.encode64(OpenSSL::Digest::SHA1.digest(string_to_sign)).chomp
puts "\nsign w/ RSA priv key"
puts Base64.encode64(OpenSSL::PKey::RSA.new(File.read("test-key.pem")).private_encrypt(string_to_sign))
Bash
#!/bin/bash
string_to_sign="Method:GET
Hashed Path:rakSQTQa55Ls8KWcrShhane6uFY=
X-Ops-Content-Hash:O8Fciq4+QSTdQJA18y6i/Wg178k=
X-Ops-Timestamp:2023-05-18T15:26:59Z
X-Ops-UserId:test-user"
echo -e "\n############################################################"
echo -e "Bash"
echo -e "\nBase64 Encoding"
echo -n "$string_to_sign" | base64
echo -e "\nSHA1 Hash"
echo -n "$string_to_sign" | openssl dgst -binary -sha1 | base64
echo -e "\nSign w/ RSA priv key"
echo -n "$string_to_sign" | openssl rsautl -sign -inkey test-key.pem | base64
echo -e ""
Python
#!/usr/bin/python
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA1
from Crypto.Signature import pkcs1_15
import base64
string_to_sign = """Method:GET
Hashed Path:rakSQTQa55Ls8KWcrShhane6uFY=
X-Ops-Content-Hash:O8Fciq4+QSTdQJA18y6i/Wg178k=
X-Ops-Timestamp:2023-05-18T15:26:59Z
X-Ops-UserId:test-user"""
print("############################################################")
print("Python")
print("\nBase64 Encoding")
print(base64.encodebytes(string_to_sign.encode()).decode().rstrip())
print("\nSHA1 Hash")
sha1_hash = SHA1.new(string_to_sign.encode())
print(base64.encodebytes(sha1_hash.digest()).decode().rstrip())
print("\nSign w/ RSA priv key")
key = RSA.importKey(open("test-key.pem").read())
h = SHA1.new(string_to_sign.encode())
signature = pkcs1_15.new(key).sign(h)
print(base64.encodebytes(signature).decode())
For reference my test-key.pem (it was generated specifically for this question and thus is a throw away key).
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEApEWOeapXklrB1dV/SAm2cPLgZ2qwJfJ+POWr2FFa7m7+JdLy
exDkxyqtbXw857/iiw+56g1/VbSxEEvauJincWGJPn6le47v/M+Cbojqv4ULw4Fh
2/4191EAjwdzJSlmXxDxbxO76qFDZnUyXstAUeyaJs549xz+H1u81tm2zU0a8cyO
SeSnHxFfEe1kMosxkC3m0aHa3pA+sxpS8vqTBFUK87u20o2WpPuq/IgxIdnxd4tJ
NNTsbKRMvw83PFpH6W5sDsWo1e8jDz92WXghOQeSqvm2uZEx5L4UAKKOwnOWNraF
GMQRRnbflow6e/HjwZJoiRjFIEFkYlJJ1vUwTQIDAQABAoIBAH5WbGwP4QfTOw5d
A2YA6kpV0NZYjB6zL/lf3dkhQKDtxhKK+ShC5uByZy00Bpdp0S6IKsDiHpNow2C4
JgAgj264x9fDiTvMw6+YXETskjY3ecOjpwKNsS2DI73cyebDv1LP8g8uizC5U9/h
tJqJEO+w2yGLXCcZKiwt3r8Sc+/R4lGIv9UsHIo6fzcHSykhPfUnlMSo1pBQ9HYB
zcF8ErGSS+UenfsSiFMxueU3iL++u1SDUl+ObVgh1FV1Ax0psse9gPp/vwgSWbKR
jljiqmFeGtpH5aCTCjXTdjG83GHzZ9The/SIw0DyfH+obMrzsnUMG7tzVIGPMuL8
8+j5gxUCgYEA+twgS8L6o3Bgc8cvsrCDcoaVVvhaGNZahzGZjxCE+zt6943mHgZ0
3oFBYoOfLS2QjLW3VbMx6czJ1Ow+9gPWGRPN01uUaiCVP+pRKNN4ixlYgY4RFuTj
9NAeIMzMY/zeRDvFwRxO2IvKQwI3Nix+hupo2eVmA7NDHSWfuSi5ce8CgYEAp6M8
dndFWPkuMSL1jU1eVWqWi8D5UiJrlNdp+1DniSNr+C/oSD/+Ot72RDDhwKe+JpP4
iUiTEpmuc1ZUOJ2um9BO4DP347UvyHRGUssS1bAlKgIvFi5CAWRgvv0cAjdpRpTU
VCe/iNE8nbTMQCj9TtQh4PaQF1f/eDarY5LlTYMCgYEA0eE/iANeTUWk/NjGmFrD
7xqYcYYhYyxb20ZtMlvg1o0CKYHn6HEAcHR17uUuVM8NZBxYgfQFq5Vxu5nYZ134
T0zZZJ73Qf92v13cfyrGbKJNAT+KHrxr2BQTUN/nlTQoBbB4mEOF1/jExWFiLgn1
5gzSopMh0bC2Uvl6c6CV3rMCgYEAgKUXQD41XJsUpKaUU9R8wQXj8+mqKyq47mcF
MNScajRhpft1wQRC4AC8cgYlKIhRtx80yn2ER/Dh3CbyyOPQ3EfWT93xrLAdtDHu
yZiHoq7jRkKYyefDxXe3ermYZecKBh0ueEpshN01LD1TxSTvhy/ps87jMtbX+PPT
QL249GsCgYAi4344fB5tsrIpdWmmQ0AO/0LokBKm7oJEYm67lGMd1V6CRGmw4xl6
6Bmu15egsxKAmNtSAs7X7MI3gjS2wmx/3z2d3NLTz1chU4/7tzhPYTZsKAkXye9v
CO7cEtAR5Va+ayzmxs6BQW14rnqDrX/0jri4nyF0yxEvDPnQsh3Hpg==
-----END RSA PRIVATE KEY-----
and here is the results I am getting:
ruby signme.rb; bash signme.sh; python signme.py;
############################################################
Ruby
Base64 Encoding
TWV0aG9kOkdFVApIYXNoZWQgUGF0aDpyYWtTUVRRYTU1THM4S1djclNoaGFu
ZTZ1Rlk9ClgtT3BzLUNvbnRlbnQtSGFzaDpPOEZjaXE0K1FTVGRRSkExOHk2
aS9XZzE3OGs9ClgtT3BzLVRpbWVzdGFtcDoyMDIzLTA1LTE4VDE1OjI2OjU5
WgpYLU9wcy1Vc2VySWQ6dGVzdC11c2Vy
sha1 Hash
lJMTFTq6/XPOwQUMKbGZdE3c5fE=
sign w/ RSA priv key
jxQHbrJlRBw5cfbpdyWvNVhfWOZtV1t0wdYPBKqGuIil5tXtzmOaXr1l21Cm
P+SdSY9+yc0eeuC1ylIoFaDf3+W61+zImW9b6zS9GnssNqogPpC1ERhXfNkv
5t2vRcg5Df3EQG5XfQb/X/7VMkoshLOGjul4If2X3jbNK4ZaIehi8A1Ie7Xm
LSllRBgOYxHDoztsGNlZz7mQQjNPCcO/nh7BPLG/2HcLZCsFOTBn8LD1EYyN
tewFD3qIoo1aWzAMvqqBXr3AHhXlh1gqq9P/adQcWYf/uGZvGs6W2juRys9y
39I4hitDk2EUW10lx3+6SZq4oqt4G5TEZP9XQYs1kw==
############################################################
Bash
Base64 Encoding
TWV0aG9kOkdFVApIYXNoZWQgUGF0aDpyYWtTUVRRYTU1THM4S1djclNoaGFuZTZ1Rlk9ClgtT3Bz
LUNvbnRlbnQtSGFzaDpPOEZjaXE0K1FTVGRRSkExOHk2aS9XZzE3OGs9ClgtT3BzLVRpbWVzdGFt
cDoyMDIzLTA1LTE4VDE1OjI2OjU5WgpYLU9wcy1Vc2VySWQ6dGVzdC11c2Vy
SHA1 Hash
lJMTFTq6/XPOwQUMKbGZdE3c5fE=
Sign w/ RSA priv key
jxQHbrJlRBw5cfbpdyWvNVhfWOZtV1t0wdYPBKqGuIil5tXtzmOaXr1l21CmP+SdSY9+yc0eeuC1
ylIoFaDf3+W61+zImW9b6zS9GnssNqogPpC1ERhXfNkv5t2vRcg5Df3EQG5XfQb/X/7VMkoshLOG
jul4If2X3jbNK4ZaIehi8A1Ie7XmLSllRBgOYxHDoztsGNlZz7mQQjNPCcO/nh7BPLG/2HcLZCsF
OTBn8LD1EYyNtewFD3qIoo1aWzAMvqqBXr3AHhXlh1gqq9P/adQcWYf/uGZvGs6W2juRys9y39I4
hitDk2EUW10lx3+6SZq4oqt4G5TEZP9XQYs1kw==
############################################################
Python
Base64 Encoding
TWV0aG9kOkdFVApIYXNoZWQgUGF0aDpyYWtTUVRRYTU1THM4S1djclNoaGFuZTZ1Rlk9ClgtT3Bz
LUNvbnRlbnQtSGFzaDpPOEZjaXE0K1FTVGRRSkExOHk2aS9XZzE3OGs9ClgtT3BzLVRpbWVzdGFt
cDoyMDIzLTA1LTE4VDE1OjI2OjU5WgpYLU9wcy1Vc2VySWQ6dGVzdC11c2Vy
SHA1 Hash
lJMTFTq6/XPOwQUMKbGZdE3c5fE=
Sign w/ RSA priv key
VSFe3su8dejyKPdLSBQU9Z0MTL7/TGrt2pA97sMqfCy2rnWtuCA28KPYA77w6vGdlTrzpWjq6fpU
ndJw3USwMcjzd5h/2XLYlpZjOP9/GYIbdayOZ3YtNl7b9GfFMcaKB+Lao5pPfuE8YMjvCDYGqpaY
uD4qUz6+zEQ8W9GlTyGDNN+QRCYDtoimK/nU0vmyLTgtx1gf9mmub1ZmfBPdhjZpF2XHJljANit7
0i+bfnE44IMYlWGdd43yPc5fxwsywNgEnkt38lQ8hiWP6KDcfgz6SN/ax9qRgpEnTF21QxMt/yfr
BLngJKdcW6TVv96uTXoU0K7VIkoFzq2PFu56ug==
customizedSign(). With this, the Ruby/Bash signature can be generated, s. online replit.com/@3hK8cL8H24hwiS7/….