BitShares Forum

Main => Technical Support => Topic started by: madforstrength on February 01, 2016, 10:28:41 am

Title: Issues in decrypting MEMO
Post by: madforstrength on February 01, 2016, 10:28:41 am
Hello Again Guyz,

Today I am having issue in decrypting the memo of transaction.

Firstly our application is on python2.7 so we cant just install python-graphenelib and use it.

Secondly even if I am installing it on my local machine when I ran memo_decode it gave me
Quote
--cannot decode-- Error loading Base58 object

So ideally I would be glad to know if there is some API that can decrypt the memo for me ;)

Or is there any script that uses python 2.7 to decrypt memo?

Or if none of the above than how can I resolve base58 issue? :(

Thanks and Regards
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 01, 2016, 11:02:03 am
afaik you can use "get_account_history <account name> <limit>" on the cli wallet to get the history which also contains a description parameter that has the decoded memo message

The base58 issue tells me that you have not provided a valid wif private key for decription of the memo
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 01, 2016, 11:16:17 am
Hi xeroc,

Thanks for your help buddy. Well I am using API to get the transaction to the merchant's account.

I have tried the memo_key found in options returned when we use "get_accounts" to fetch account details but now I am getting this error:

Quote
--cannot decode-- (33, 32)

Also "get_account_history" is not available in database API and I can't use CLI for this due to nature of my application.
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 01, 2016, 12:20:29 pm
Hi xeroc,

Thanks for your help buddy. Well I am using API to get the transaction to the merchant's account.

I have tried the memo_key found in options returned when we use "get_accounts" to fetch account details but now I am getting this error:

Quote
--cannot decode-- (33, 32)

This is how the memo module is supposed to be used:
Code: [Select]
from graphenebase import Memo, PrivateKey, PublicKey
memo = {"from": "GPH6Co3ctgs6BSsGkti3iVcArMKywbwhnzKDAgmkb6J3Cad7ykDYX",
        "to": "GPH7gU4pHJ9rTUfVA6q6dEgCxgMGVLmq1YM3HRAKpj1VnTzJhrAn2",
        "nonce": "9729217759611568577",
        "message": "aac432f92a8bf52828ac1fda8a3bf6e3"}
priv = PrivateKey("WIF-KEY")
pub = PublicKey("OTHERS-PUBKEY", prefix="GPH")
dec = decode_memo(priv, pub, memo["nonce"], memo["message"])
print(dec)

Quote
Also "get_account_history" is not available in database API and I can't use CLI for this due to nature of my application.
That is true. the get_account_history api is only available in the
history_api and the one implemented in the witness node will NOT decode
the memo because it does not have the private key anywhere. Only the cli
wallet has the private keys.

The only way to work this out for you is to either write a memo decoding
wrapper that uses python3 or to migrate the code over to python2.. not
sure what needs to be done to do that though ..
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 01, 2016, 12:24:36 pm
@xeroc yes I am using the same script you mentioned.
Actually my application does not store merchants private key, is there anyway I can get it through API call?

This is the exact script I am using

Code: [Select]
wifkey = "BTS81JWvhxW5YQ52rDC2fzCddi3BopYrEtT2qza3qu55s7iFAjLLo"
from graphenebase import Memo, PrivateKey, PublicKey
memo = {
                        "from": "BTS8citBkJYULm8oRsscFbU277GwPMm2NaELESncQqBgynyoKeFK8",
                        "to": "BTS81JWvhxW5YQ52rDC2fzCddi3BopYrEtT2qza3qu55s7iFAjLLo",
                        "nonce": "8864538374045458127",
                        "message": "47db5a59f700b4df2ab7fdcafe638404"
                    }
priv = PrivateKey(wifkey)
pub = PublicKey(memo["from"], prefix="GPH")
dec = decode_memo(priv, pub, memo["nonce"], memo["message"])
print(dec)

And it is giving me this error:
Code: [Select]
Traceback (most recent call last):
  File "memo/memo_test.py", line 11, in <module>
    priv = PrivateKey(wifkey)
  File "/home/developer03/.local/lib/python3.4/site-packages/graphenelib-0.3rc1-py3.4.egg/graphenebase/account.py", line 249, in __init__
  File "/home/developer03/.local/lib/python3.4/site-packages/graphenelib-0.3rc1-py3.4.egg/graphenebase/account.py", line 258, in compressedpubkey
  File "/usr/local/lib/python3.4/dist-packages/ecdsa/keys.py", line 149, in from_string
    assert len(string) == curve.baselen, (len(string), curve.baselen)
AssertionError: (33, 32)
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 01, 2016, 12:28:26 pm
private keys are "private"
If you want to have the memo decrypted you NEED to provide the memo key.
you may want to take a look at this script:
https://github.com/xeroc/python-graphenelib/blob/master/scripts/monitor-deposits/monitor.py

what merchant app are you building? Is this the POS project of bts-munich or another project?
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 02, 2016, 04:37:38 am
@xeroc lemme explain what I am doing,

Well I am working on developing a payment gateway for bitshares in my project, I have created the invoice successfully, now when a user makes payment then he is redirected to my url along with block and transaction numbers.

I then call API with this data to get the whole transaction.
E.g.
Code: [Select]
{"id":1,"method":"get_transaction","params":[3153947,0]}
The API returns me transaction details like (to, from, amount and memo). but memo is encrypted :(

So I call the API again for getting the account to which payment was made.
E.g. 
Code: [Select]
{"id":1,"method":"get_accounts","params":[["1.2.96993"]]}
I extract the memo key from options and then use this memo key as wif key in your code but still getting the following error:

Code: [Select]
Traceback (most recent call last):
  File "memo/memo_test.py", line 11, in <module>
    priv = PrivateKey(wifkey)
  File "/home/developer03/.local/lib/python3.4/site-packages/graphenelib-0.3rc1-py3.4.egg/graphenebase/account.py", line 249, in __init__
  File "/home/developer03/.local/lib/python3.4/site-packages/graphenelib-0.3rc1-py3.4.egg/graphenebase/account.py", line 258, in compressedpubkey
  File "/usr/local/lib/python3.4/dist-packages/ecdsa/keys.py", line 149, in from_string
    assert len(string) == curve.baselen, (len(string), curve.baselen)
AssertionError: (33, 32)
Title: Re: Issues in decrypting MEMO
Post by: monsterer on February 02, 2016, 08:41:25 am
@xeroc yes I am using the same script you mentioned.
Actually my application does not store merchants private key, is there anyway I can get it through API call?

You decode a memo using the sender's public memo key, and the private key from the receipient's account
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 02, 2016, 09:16:23 am
@monsterer I understand that, but the problem is I dont have receiver's private key, so can I get it through API call or is there any other method which do not require private key for decrypting memo?
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 02, 2016, 10:47:57 am
@xeroc lemme explain what I am doing,

Well I am working on developing a payment gateway for bitshares in my project, I have created the invoice successfully, now when a user makes payment then he is redirected to my url along with block and transaction numbers.

I then call API with this data to get the whole transaction.
E.g.
Code: [Select]
{"id":1,"method":"get_transaction","params":[3153947,0]}
The API returns me transaction details like (to, from, amount and memo). but memo is encrypted :(

So I call the API again for getting the account to which payment was made.
E.g. 
Code: [Select]
{"id":1,"method":"get_accounts","params":[["1.2.96993"]]}
I extract the memo key from options and then use this memo key as wif key in your code but still getting the following error:

Code: [Select]
Traceback (most recent call last):
  File "memo/memo_test.py", line 11, in <module>
    priv = PrivateKey(wifkey)
  File "/home/developer03/.local/lib/python3.4/site-packages/graphenelib-0.3rc1-py3.4.egg/graphenebase/account.py", line 249, in __init__
  File "/home/developer03/.local/lib/python3.4/site-packages/graphenelib-0.3rc1-py3.4.egg/graphenebase/account.py", line 258, in compressedpubkey
  File "/usr/local/lib/python3.4/dist-packages/ecdsa/keys.py", line 149, in from_string
    assert len(string) == curve.baselen, (len(string), curve.baselen)
AssertionError: (33, 32)

That is now how you decrypt a memo.
The key that is used to encrypt the memo is derived from the senders private key and the receivers public memo key. This gives a shared secret that also the receiver can derive from HIS memo private key and the SENDERS public memo key. Taking only the public key will not allow you to encrypt it .. you will ALSO need the private key of YOUR MEMO KEY (which starts with 5 and has to be pasted as the 'wifkey' in the demo above)
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 02, 2016, 10:49:20 am
@monsterer I understand that, but the problem is I dont have receiver's private key, so can I get it through API call or is there any other method which do not require private key for decrypting memo?

>>> get_account <account name>

Take the public key that is given as "memo_key" in the options

>>> get_private_key <memo-pubkey>
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 02, 2016, 11:15:48 am
@xeroc Thanks buddy but get_private_key is not available in DATABASE API :(

Now the only option I can think of is creating a full node of my own and write a wrapper that will take my API calls and return me my desired information.

is there any other way?
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 02, 2016, 12:27:21 pm
the database api is ONLY for reading blockchain stuff. It does not deal with private keys at all. You NEED to open the cli-wallet to get the private key for your account.
Once you have the private key, you can put it into your script and don't need to use the cli wallet any longer.
http://docs.bitshares.eu/integration/apps/index.html
Title: Re: Issues in decrypting MEMO
Post by: monsterer on February 02, 2016, 02:33:55 pm
@monsterer I understand that, but the problem is I dont have receiver's private key, so can I get it through API call or is there any other method which do not require private key for decrypting memo?

What is your use case? Why do you need to try and decrypt memos which don't belong to you?
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 03, 2016, 04:12:08 am
@monsterer I am building an app that will enable a merchant to allow his customers to pay through smartcoins. So my app will be used by many different merchants all he need to do is enter his bitshares account name and select the currency which he wants to accept.

@xeroc I cant just hard code my private key in the application because every merchant will have his own key. So in order to decrypt the memo of transaction sent to a specific merchant i need the private key of this merchant mine will not be able to decrypt it :(
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 03, 2016, 06:55:26 am
@monsterer I am building an app that will enable a merchant to allow his customers to pay through smartcoins. So my app will be used by many different merchants all he need to do is enter his bitshares account name and select the currency which he wants to accept.

@xeroc I cant just hard code my private key in the application because every merchant will have his own key. So in order to decrypt the memo of transaction sent to a specific merchant i need the private key of this merchant mine will not be able to decrypt it :(
If you let merchants use their own account names, then you either need to let them replace the memo key to a key that you have the private key hard coded (not so good idea), or your need to ask the merchant for the memo private key as well ..
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 03, 2016, 07:16:07 am
@xeroc Can I ask the merchants for private key? won't they be hesitating in entering their private?

This will make my job a lot easier, but I dont know if it will be acceptible or not, as private keys are confidential.

Well right now I have established a trusted node on my local machine

here: https://github.com/bitshares/bitshares-2 (https://github.com/bitshares/bitshares-2) I found:
Quote
Is there a way to allow external program to drive cli_wallet via websocket, JSONRPC, or HTTP?

Yes. External programs may connect to the CLI wallet and make its calls over a websockets API. To do this, run the wallet in server mode, i.e. cli_wallet -s "127.0.0.1:9999" and then have the external program connect to it over the specified port (in this example, port 9999).

If it is possible to create a websocket for CLI wallet then I can simply call this socket from my application and use either get_transaction_history or get_private_key

Am i right?
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 03, 2016, 07:24:03 am
the memo private key can only be used to decrypt memos .. unless the account is setup strangely it cannot be used to access the account or its funds.

Technically, the memokey can be obtained via RPC call to the cli wallet, but if your merchant app is able to read a qr code, i would recommend to let the mrchant scan the memo priv key instead
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 03, 2016, 07:30:12 am
Technically, the memokey can be obtained via RPC call to the cli wallet, but if your merchant app is able to read a qr code, i would recommend to let the mrchant scan the memo priv key instead

Sorry @xeroc I can't understand above point. What do you mean by let the merchant scan the memo priv key? DO you mean let the merchant enter the memo priv key?
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 03, 2016, 10:26:51 am
Ok I have tried everything now :(

I have used get_private_key but its giving error because:
Quote
The private key must already be in the wallet.

I have also tried get_account_history, it is showing me the transactions but with error:
Quote
Memo is encrypted to a key BTS81JWvhxW5YQ52rDC2fzCddi3BopYrEtT2qza3qu55s7iFAjLLo not in this wallet.

Now I guess there is no way I can get someone's private key programmatically. :(

Would appreciate if someone can verify this or identify any other method to get the private key of any account through api or wallet.
Thanks
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 03, 2016, 12:08:01 pm
Every account has 3 key pairs. One of which is for memo encryption/decryption.
Each pair consists of a pub and a private key.
The "pubkey" is used to encrypt the message for the recepient so that the recipient can only decrypt if he HAS the private key.
Usually, the wallet that has created the account and has access to its funds also has access to its memo private key.

Unless you have access to that wallet (i.e. private key) there is NO WAY to decrypt the encrypted memo!
Title: Re: Issues in decrypting MEMO
Post by: madforstrength on February 04, 2016, 05:08:51 am
ok @xeroc thanks for your valuable input. Just one more thing, is there any way to validate that the private key entered by the merchant is correct? and belongs to his account?
Title: Re: Issues in decrypting MEMO
Post by: xeroc on February 04, 2016, 07:59:51 am
you can derive the public key from the private key:
https://github.com/xeroc/python-graphenelib/blob/master/graphenebase/account.py#L250

something along the lines of

bts_pubkey = format(PrivateKey("5........"), "BTS")