pynacl
pynacl copied to clipboard
Signature verification failure when using URLSafeBase64Encoder
I have been experimenting with pynacl (1.3.0) using python3 (3.5.2) Using the examples on https://pynacl.readthedocs.io/en/stable/signing/, I construct this minimum example:
import nacl.encoding
import nacl.signing
message = b"Attack at Dawn"
# Generate a new random signing key
signing_key = nacl.signing.SigningKey.generate()
# Sign a message with the signing key
signed = signing_key.sign(message, encoder=nacl.encoding.HexEncoder)
# Obtain the verify key for a given signing key
verify_key = signing_key.verify_key
# Check the validity of a message's signature
# The message and the signature can either be passed separately or
# concatenated together. These are supposed to be equivalent:
verify_key.verify(signed, encoder=nacl.encoding.HexEncoder) #this line verifies
verify_key.verify(signed.message, signed.signature, encoder=nacl.encoding.HexEncoder) #this line also verifies, since they are the same
print("All is well")
This works fine. However, if we change the encoding type to URLSafeBase64Encoder, as in the following minimum example
import nacl.encoding
import nacl.signing
message = b"Attack at Dawn"
# Generate a new random signing key
signing_key = nacl.signing.SigningKey.generate()
# Sign a message with the signing key
signed = signing_key.sign(message, encoder=nacl.encoding.URLSafeBase64Encoder)
# Obtain the verify key for a given signing key
verify_key = signing_key.verify_key
# Check the validity of a message's signature
# The message and the signature can either be passed separately or
# concatenated together. These are supposed to be equivalent:
verify_key.verify(signed, encoder=nacl.encoding.URLSafeBase64Encoder) #this line verifies
verify_key.verify(signed.message, signed.signature, encoder=nacl.encoding.URLSafeBase64Encoder) #THIS LINE DOES NOT VERIFY
print("All is well")
I get the following trace
Traceback (most recent call last):
File "testing_nacl.py", line 19, in <module>
verify_key.verify(signed.message, signed.signature, encoder=nacl.encoding.URLSafeBase64Encoder) #THIS LINE DOES NOT VERIFY
File "/home/username/.local/lib/python3.5/site-packages/nacl/signing.py", line 112, in verify
return nacl.bindings.crypto_sign_open(smessage, self._key)
File "/home/username/.local/lib/python3.5/site-packages/nacl/bindings/crypto_sign.py", line 111, in crypto_sign_open
raise exc.BadSignatureError("Signature was forged or corrupt")
nacl.exceptions.BadSignatureError: Signature was forged or corrupt
I think there is a bug with the URLSafeBase64Encoder in this case.
This kind of weirdness is the reason why we are discussing, about removing support from the encoding= parameter since @alex comment in https://github.com/pyca/pynacl/pull/504#issuecomment-454233998 and my later #523 PR.