-
Notifications
You must be signed in to change notification settings - Fork 86
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
BSIP-SIGNED-MESSAGE #158
Comments
Please change BSIP type to "Informational (Client Protocol)". Why is the IMO it's a bad idea to use a PGP-like plain string representation, precisely because PGP has had a lot of difficulties with this. At the very least, you must define precisely how whitespace and end-of-line characters are to be handled. The |
yep, JS arrays are deterministic order. objects (which would allow name/value pairs) are not |
Haha ... very good point, we ran into those problems too. ECDSA is used on the secp256k1 curve. signature is presented in hexadecimal format and is prepended with signature recovery parameter. So, the signature is generated by hashing the stringified content, and signing the hash the very same way bitshares signs transactions. |
What about embedded whitespace / EOL chars? What about encoding? JSON is utf-8 but plaintext is platform-dependent. How is the string hashed? Transaction hashing prepends the chain ID, is that also required here? |
I will check and fill in details for that (the plain text one is already existing in the UI that is why I want a post-published definition for it). Ideally the UI also switches away from it. |
Yes, it does - and IMHO should because accounts on different chains could be owned by different people. The encoding, I suppose should be properly defined ... wouldn't it be easiest to allow UTF-8 everywhere and encode it as such? |
JSON strings can contain backslash escapes, which means there is no canonical representation either. |
Why timestamp is a |
IMO this BSIP should mention the existing message signing method used by python and JS libraries. Implementations should also accept messages signed using that old format, but produce signatures in the new format. |
Raw String Version 1 is the current one. |
IMHO string is more read-able than a UNIX timestamp integer. |
Oh, right. Sorry. |
This should be a draft in the repository but not only an issue. |
IMHO the metadata should be dropped from the spec, as it effectively makes the metadata part of the signature. In other words, to verify the signature of a message, the verifier would need to be in possession of both the signature and the metadata. This means the following script between Valarie Validator and Bob Signer wouldn't work:
The problem is, Valerie cannot validate this signature, unless Bob also provides the metadata, which at best is cumbersome, and at worst may not be possible, if they are using a communication protocol that does not allow for this extra data. A validator should be able to validate a known message with the signature bytes alone. |
@christophersanborn I know this issue has been open a long time, but I worked up an example for my own learning and thought I would share. Of course, if you implemented a BitShares app using this modified protocol you couldn't send messages from your app to existing BitShares users who are using the web UI, for example. So, I wouldn't recommend it. But, I think it's good just to see how to verify a signature independant from the messaging protocol. It seems like the meta data is redundant to me, because all that data can be derived from the blockchain itself. But, I am curious to learn from others what the thought process is behind including the meta data. Maybe I'm missing something. import json, binascii, unittest
from graphenebase import BrainKey, memo
from graphenebase.ecdsa import sign_message, verify_message
class message_signing_Tests(unittest.TestCase):
receiver_brainkey = BrainKey(
brainkey='DANLI ARTHEL SOREDIA BASKER IDYL SAMMY RUFTER IDEATE TITULUS CUTUP BORGH PERIOST ARETE BANDIE MIDE BIPEDAL',
prefix='TEST',
sequence=0,
)
sender_brainkey = BrainKey(
brainkey='BELTER QUEASY TAGRAG PAXILLA COUXIA PAPISM HELM WISTE STILTY INDITER STARNEL CURIATE MAFFIA LOTS RHABDUS BEDWAY',
prefix='TEST',
sequence=0,
)
salt = datetime.utcnow()
def setUp(self) -> None:
super().setUp()
self.text = 'What is the Ultimate Question of Life, the Universe, and Everything?'
self.payload = [
'from',
'user-one',
'key',
str(self.sender_brainkey.get_public_key()),
'time',
str(self.salt),
'text',
self.text,
]
self.payload_encoded = json.dumps(self.payload, separators=(",", ":"))
def test_sign_verify_and_encrypt_payload(self):
# sign the JSON encoded payload
self.signature = binascii.hexlify(
sign_message(
self.payload_encoded,
str(self.sender_brainkey.get_private_key()),
)
).decode('ascii')
# verify the signature
self.sender_pubkey = binascii.hexlify(
verify_message(
self.payload_encoded,
binascii.unhexlify(self.signature),
)
).decode('ascii')
self.assertEqual(
repr(self.sender_brainkey.get_public_key()),
self.sender_pubkey,
)
# receiver encrypts the message into a BitShares memo.
self.memo_encrypted = memo.encode_memo(
self.sender_brainkey.get_private_key(),
self.receiver_brainkey.get_public_key(),
self.salt,
self.payload_encoded,
)
# print message
msg = '-----BEGIN BITSHARES SIGNED MESSAGE-----\n'
msg += f'{self.text}\n'
msg += '-----BEGIN SIGNATURE-----\n'
msg += f'{self.signature}\n'
msg += '-----END BITSHARES SIGNED MESSAGE-----'
print(msg) Which, would yield this output:
|
I think the meta data is to avoid replay attacks. |
Ahh that does make sense. |
Abstract
This is an informal BSIP to define the format of a signed message to establish a common format.
Specification
Raw String Version 1
Plain String version with header and footer, similar to PGP message. Everything is a string, thus no quotation marks are present.
user_message
account_name
public_key
head_block_no
datetime_string
Date.toString()
)signature
The string payload for signing is
represented as a string with visible characters
Example
JSON Version 1
Represented as a dictionary, a signed message in JSON Version 1 looks like
user_message
account_name
public_key
timestamp
signature
The string payload for signing is
which corresponds to the stringified version of the JSON payload defined previously.
Example
The text was updated successfully, but these errors were encountered: