Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode smessage #504

Merged
merged 4 commits into from
Jan 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 122 additions & 9 deletions docs/signing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ use it to validate that your messages are actually authentic.
Example
-------

Signing and verifying a message without encoding the key or message

Signer's perspective (:class:`~nacl.signing.SigningKey`)

.. testcode::

import nacl.encoding
import nacl.signing
from nacl.signing import SigningKey

# Generate a new random signing key
signing_key = nacl.signing.SigningKey.generate()
signing_key = SigningKey.generate()

# Sign a message with the signing key
signed = signing_key.sign(b"Attack at Dawn")
Expand All @@ -34,21 +35,21 @@ Signer's perspective (:class:`~nacl.signing.SigningKey`)
verify_key = signing_key.verify_key

# Serialize the verify key to send it to a third party
verify_key_hex = verify_key.encode(encoder=nacl.encoding.HexEncoder)
verify_key_bytes = verify_key.encode()

Verifier's perspective (:class:`~nacl.signing.VerifyKey`)

.. testcode::

import nacl.signing
from nacl.signing import VerifyKey

# Create a VerifyKey object from a hex serialized public key
verify_key = nacl.signing.VerifyKey(verify_key_hex,
encoder=nacl.encoding.HexEncoder)
verify_key = VerifyKey(verify_key_bytes)

# Check the validity of a message's signature
# The message and the signature can either be passed separately or
# concatenated together. These are equivalent:
# The message and the signature can either be passed together, or
# separately if the signature is decoded to raw bytes.
# These are equivalent:
verify_key.verify(signed)
verify_key.verify(signed.message, signed.signature)

Expand All @@ -65,6 +66,118 @@ Verifier's perspective (:class:`~nacl.signing.VerifyKey`)
nacl.exceptions.BadSignatureError: Signature was forged or corrupt


Example
-------

Signing and verifying a message encoded with HexEncoder

Signer's perspective (:class:`~nacl.signing.SigningKey`)

.. testcode::

from nacl.encoding import HexEncoder
from nacl.signing import SigningKey

# Generate a new random signing key
signing_key = SigningKey.generate()

# Sign a message with the signing key
signed_hex = signing_key.sign(b"Attack at Dawn", encoder=HexEncoder)

# Obtain the verify key for a given signing key
verify_key = signing_key.verify_key

# Serialize the verify key to send it to a third party
verify_key_hex = verify_key.encode(encoder=HexEncoder)

Verifier's perspective (:class:`~nacl.signing.VerifyKey`)

.. testcode::

from nacl.encoding import HexEncoder
from nacl.signing import VerifyKey

# Create a VerifyKey object from a hex serialized public key
verify_key = VerifyKey(verify_key_hex, encoder=HexEncoder)

# Check the validity of a message's signature
# The message and the signature can either be passed together, or
# separately if the signature is decoded to raw bytes.
# These are equivalent:
verify_key.verify(signed_hex, encoder=HexEncoder)
signature_bytes = HexEncoder.decode(signed_hex.signature)
verify_key.verify(signed_hex.message, signature_bytes,
encoder=HexEncoder)

# Alter the signed message text
forged = signed_hex[:-1] + bytes([int(signed_hex[-1]) ^ 1])
# Will raise nacl.exceptions.BadSignatureError, since the signature check
# is failing
verify_key.verify(forged)

.. testoutput::

Traceback (most recent call last):
...
nacl.exceptions.BadSignatureError: Signature was forged or corrupt


Example
-------

Signing and verifying a message encoded with Base64Encoder

Signer's perspective (:class:`~nacl.signing.SigningKey`)

.. testcode::

from nacl.encoding import Base64Encoder
from nacl.signing import SigningKey

# Generate a new random signing key
signing_key = SigningKey.generate()

# Sign a message with the signing key
signed_b64 = signing_key.sign(b"Attack at Dawn", encoder=Base64Encoder)

# Obtain the verify key for a given signing key
verify_key = signing_key.verify_key

# Serialize the verify key to send it to a third party
verify_key_b64 = verify_key.encode(encoder=Base64Encoder)

Verifier's perspective (:class:`~nacl.signing.VerifyKey`)

.. testcode::

from nacl.encoding import Base64Encoder
from nacl.signing import VerifyKey

# Create a VerifyKey object from a base64 serialized public key
verify_key = VerifyKey(verify_key_b64, encoder=Base64Encoder)

# Check the validity of a message's signature
# The message and the signature can either be passed together, or
# separately if the signature is decoded to raw bytes.
# These are equivalent:
verify_key.verify(signed_b64, encoder=Base64Encoder)
signature_bytes = Base64Encoder.decode(signed_b64.signature)
verify_key.verify(signed_b64.message, signature_bytes,
encoder=Base64Encoder)

# Alter the signed message text
forged = signed_b64[:-1] + bytes([int(signed_b64[-1]) ^ 1])
# Will raise nacl.exceptions.BadSignatureError, since the signature check
# is failing
verify_key.verify(forged)

.. testoutput::

Traceback (most recent call last):
...
nacl.exceptions.BadSignatureError: Signature was forged or corrupt


Reference
---------

Expand Down
8 changes: 4 additions & 4 deletions src/nacl/signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ def verify(self, smessage, signature=None, encoder=encoding.RawEncoder):
if signature is not None:
# If we were given the message and signature separately, combine
# them.
smessage = signature + smessage

# Decode the signed message
smessage = encoder.decode(smessage)
smessage = signature + encoder.decode(smessage)
else:
# Decode the signed message
smessage = encoder.decode(smessage)

return nacl.bindings.crypto_sign_open(smessage, self._key)

Expand Down
37 changes: 35 additions & 2 deletions tests/test_signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from utils import assert_equal, assert_not_equal, read_crypto_test_vectors

from nacl.bindings import crypto_sign_PUBLICKEYBYTES, crypto_sign_SEEDBYTES
from nacl.encoding import HexEncoder
from nacl.encoding import Base64Encoder, HexEncoder
from nacl.exceptions import BadSignatureError
from nacl.signing import SignedMessage, SigningKey, VerifyKey

Expand Down Expand Up @@ -149,7 +149,8 @@ def test_valid_signed_message(
key.verify(signed, encoder=HexEncoder),
) == message
assert binascii.hexlify(
key.verify(message, signature, encoder=HexEncoder),
key.verify(message, HexEncoder.decode(signature),
encoder=HexEncoder),
) == message

def test_invalid_signed_message(self):
Expand All @@ -167,6 +168,38 @@ def test_invalid_signed_message(self):
forged = SignedMessage(signature + message)
skey.verify_key.verify(forged)

def test_base64_smessage_with_detached_sig_matches_with_attached_sig(self):
sk = SigningKey.generate()
vk = sk.verify_key

smsg = sk.sign(b"Hello World in base64", encoder=Base64Encoder)

msg = smsg.message
b64sig = smsg.signature

sig = Base64Encoder.decode(b64sig)

assert vk.verify(msg, sig, encoder=Base64Encoder) == \
vk.verify(smsg, encoder=Base64Encoder)

assert Base64Encoder.decode(msg) == b"Hello World in base64"

def test_hex_smessage_with_detached_sig_matches_with_attached_sig(self):
sk = SigningKey.generate()
vk = sk.verify_key

smsg = sk.sign(b"Hello World in hex", encoder=HexEncoder)

msg = smsg.message
hexsig = smsg.signature

sig = HexEncoder.decode(hexsig)

assert vk.verify(msg, sig, encoder=HexEncoder) == \
vk.verify(smsg, encoder=HexEncoder)

assert HexEncoder.decode(msg) == b"Hello World in hex"

def test_key_conversion(self):
keypair_seed = (b"421151a459faeade3d247115f94aedae"
b"42318124095afabe4d1451a559faedee")
Expand Down