Looking for help: how to verify if a Hive message is signed correctly in Python Beem. UPDATED!

in STEMGeeks2 months ago (edited)

The story so far.... my Python/Flask website now manages to fire up Hive Keychain thanks to help from @rishi556. I even manage to get the answer in the form of a json response back into the Python Flask back end:

As JSON that looks like this:

{
  "data": {
    "key": "posting",
    "message": "{\"signed_message\":{\"type\":\"login\",\"address\":\"brianoflondon\",\"page\":\"http://127.0.0.1:5000/podcaster/login\"},\"timestamp\":1613710433}",
    "method": "Posting",
    "request_id": 3,
    "type": "signBuffer",
    "username": "brianoflondon"
  },
  "error": null,
  "message": "Message signed succesfully.",
  "publicKey": "STM7B1eanwUQhXa8tdabTi2RxHnXWtyMBd6iJDZ3Z2QA6rKHQY2WJ",
  "request_id": 3,
  "result": "2031e828c6673b945a14489e23a90d5502238d56fb4df568e6ab88af703a9e3bba14ea410bed5afcb42b3d164c976a49645ee2848a8b65fbd9cc77cbc574ae2ffd",
  "success": true
}

Shhh don't tell anyone but right now the only bit my server looks at is the "success":true.

I've taken a look at the Beem Docs and even searched all of github, but there's minimal explanation here.

Can anyone else help with the python to do this?

Thanks in wondrous anticipation! I fully intent to make a very simple, reference and open source implementation of this kind of Hive Keychain interaction with Python Flask.

And huge thanks again to @crokkon:

I will publish the entire system including the javascript and the server side code when I get a chance.

#!/usr/bin/python
from beemgraphenebase.account import PublicKey
from beemgraphenebase.ecdsasig import verify_message
from binascii import hexlify, unhexlify

def validate_hivekeychain_ans(ans):
    """ takes in the answer from hivekeychain and checks everything """
    """ http://bit.ly/keychainpython """

    acc_name = ans['data']['username']
    pubkey = PublicKey(ans['publicKey'])
    enc_msg = ans['data']['message']
    signature = ans['result']

    msgkey = verify_message(enc_msg, unhexlify(signature))
    pk = PublicKey(hexlify(msgkey).decode("ascii"))
    if str(pk) == str(pubkey):
        print("SUCCESS: signature matches given pubkey")
        acc = Account(acc_name)
        match = False, 0
        for key in acc['posting']['key_auths']:
            match = match or ans['publicKey'] in key
        if match:
            print('Matches public key from Hive')
            mtime = json.loads(enc_msg)['timestamp']
            time_since = time.time() - mtime
            if time_since < 30:
                return True , time_since
            else:
                print("ERROR: answer took too long.")
    else:
        print("ERROR: message was signed with a different key")
        return False, 0

brianoflondon hive footer.png

Posted with STEMGeeks

Sort:  

Not sure why you are using Flask, but if you want to use a python/django implementation.

We do this in the Holybread code and I could give you access to the Github rep, for you to look at.

Not sure what you are not receiving back and what you are trying to do.

Is it just simple logins?

Posted Using LeoFinance Beta

I'm pretty sure flask and Django would be very similar in this.

I just want to confirm the user by checking they can sign a message with their posting key.

This is my github account : https://github.com/brianoflondon

#!/usr/bin/python
#!/usr/bin/python
from beemgraphenebase.account import PublicKey
from beemgraphenebase.ecdsasig import verify_message
from binascii import hexlify, unhexlify

msg = {'data': {'key': 'posting', 'message': '{"signed_message":{"type":"login","address":"brianoflondon","page":"http://127.0.0.1:5000/podcaster/login"},"timestamp":1613710433}', 'method': 'Posting', 'request_id': 3, 'type': 'signBuffer', 'username': 'brianoflondon'}, 'error': None, 'message': 'Message signed succesfully.', 'publicKey': 'STM7B1eanwUQhXa8tdabTi2RxHnXWtyMBd6iJDZ3Z2QA6rKHQY2WJ', 'request_id': 3, 'result': '2031e828c6673b945a14489e23a90d5502238d56fb4df568e6ab88af703a9e3bba14ea410bed5afcb42b3d164c976a49645ee2848a8b65fbd9cc77cbc574ae2ffd', 'success': True}

pubkey = PublicKey(msg['publicKey'])
enc_msg = msg['data']['message']
signature = msg['result']

msgkey = verify_message(enc_msg, unhexlify(signature))
pk = PublicKey(hexlify(msgkey).decode("ascii"))
if str(pk) == str(pubkey):
    print("SUCCESS: signature matches given pubkey")
else:
    print("ERROR: message was signed with a different key")

This could help you to move forward. I'm not sure about the 'best practices' for keychain authentication. You could extend this by verifying that the pubkey provided with the message is actually the posting key of the given account.

I added one more enhancement to check if the answer is older than 30 seconds... Thank you so much! This is a very important part of what I'm doing.

I absolutely will make a very clear post about this soon.

glad I could help.

[...] to check if the answer is older than 30 seconds.

Is that a timeout you chose, or is this coming from keychain? Thinking about my own usage of keychain, I might need more than 30 seconds from clicking 'sign in' until the signed message is sent - esp. if my keychain is locked and I have to find the keychain password first...

Hmmmm I'm so used to having Keychain unlocked I'll try locking it and perhaps upping the timeout to 5 mins. I doubt that replay attacks will be a huge issue!

Posted using Dapplr

Congrats, you were upvoted from this account because you were in Top 25 engagers yesterday on STEMGeeks .
You made a total of 3 comments and talked to 2 different authors .
Your rank is 3 .
For more details about this project please read here - link to announcement post
You can also delegate and get weekly payouts.

Loading...

Congrats, you were upvoted from this account because you were in Top 25 engagers yesterday on STEMGeeks .
You made a total of 1 comments and talked to 1 different authors .
Your rank is 4 .
For more details about this project please read here - link to announcement post
You can also delegate and get weekly payouts.

Can we build an encrypted chat like whatsapp based on memo features ?

PeakD has a chat built in. Try it.

Congratulations @brianoflondon! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s) :

You distributed more than 42000 upvotes.
Your next target is to reach 43000 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out the last post from @hivebuzz:

Hive Tour Update - Communities
Hive Tour Update - Advanced posting