Changing Recovery Account with dsteem API: Possible Precursor to Hardware Wallet

avatar

recoveryroadintosunlight760.jpg

I am very nervous about the security of my account right now. @steem (Steemit Inc) can not be trusted to recover my account should my owner/master key get compromised.

If my owner/master key gets stolen right now, that's it, I lose everything.
The keys for both platforms are the same, so I would lose both.

The simple solution is to change the recovery account asap. However, to change the recovery account one ironically has to sign with their owner key. I maintain that this is a foolish way to handle account security.

It already takes 30 days for recovery accounts to officially migrate. If someone hacks my active key and tries to change the recovery account, I have more than enough time to fix the issue. Active key security should be the only requirement for changing the recovery account. I'm very annoyed right now.

To the point that I'm even powering down my account just so I won't be risking so many coins in the process of changing my recovery account. This wouldn't be a big deal if I knew how to sign transactions with my private key offline and then broadcast the public transaction later on another machine. That is simply not the case. I have no idea how to do this or even if it is possible with the current tech.

Would I trade all my coins for my reputation?

An interesting aside here, if I could choose between losing all my coins and keeping my account vs losing my account and keeping all my coins, what would I do? I really have no idea. Like @theycallmedan has stated before:

You can't buy time.

The reputation and social network I've garnered here can't be bought with dollars. It is possible the the USD value of my account today could be generated in a couple weeks just from a dozen blog posts during an epic bull run the likes of which we saw during 2017. Food for thought.

I don't have the owner key for my account.

Yep. I never wrote down the owner key. I never understood the point of it until now. Turns out, back in day the frontends I was using were actually using my master key to generate the other keys in the background and using those keys to sign transactions. The same frontends of today don't allow this because it's a pretty major security issue.

So basically not only do I need to change my recovery account, I also need to generate my Owner key so I can sign that transaction in the first place. Anyone who does this on a frontend like PeakD or steemworld is trusting the centralized owner of said websites. Not saying they aren't trustworthy, only that we're supposed to be building trustless contracts. When it comes to a situation as serious as this frontends should not be the default option.

Here's where I'm at so far:

t2.png

So I was looking at the dsteem API wondering how I was going to broadcast the transaction myself. The majority of the things I've done with dsteem have involved either the BroadcastAPI or the DatabaseAPI. At first I thought I'd be able to use the DatabaseAPI call() function to get this done, but then I realized that's not going to work because database functions don't get signed with a key, it's just a query from the node you're connected to.

When I checked BroadcastAPI it wasn't there either. This is a good example of how poor our documentation is. There are very few examples and sometimes it can take forever just to figure out what the syntax of certain statements are supposed to look like. This is especially true for me personally because I am not running a node or using Node.JS, so a lot of the examples that do exist do not apply to me because I'm trying to do everything using pure JavaScript and basic HTML.

t3.png


So I scrolled down and found what I was looking for.


t3.png

t3.png

However, what I see is a bit confusing.

It appears as though this operation is a "generic operation", and I've never broadcasted a generic operation before.

t3.png

Apparently there are a lot of random generic operations. It appears that a generic operation is an array with 2 parts. The first part (0) is a string that tells the platform which generic operation is being called (in this case 'change_recovery_account'). The second part is an object with attributes. 'change_recovery_account' has three attributes:

  • account_to_recover
  • extensions
  • new_recovery_account

To confirm all this, I took a look away from dsteem documentation and into Hive documentation.

I found what I was looking for.

t3.png


But I still didn't know how to broadcast a generic operation!

So I looked back into the Broastcast API and found this:


t3.png

Hey now! This looks promising!

It appears as though sendOperations() can broadcast multiple operations at the same time. Pretty cool... because I was actually wondering how it was possible to send more than one operation on a single block. This is it. However, in this case I'm just sending one operation so I'll just use an array of length one... which is redundant but I've all ready done so much work for so little payoff I don't give a fuck.

So yesterday I wrote a script:

<script src="https://unpkg.com/[email protected]^0.10.0/dist/dsteem.js"></script>

Account:
<input type="text" id="account" value="smartasscards"><br>
Owner Key:
<input type="password" id="key_string"
value=''><br>
New recovery account:
<input type="text" id="recovery" value='v4vapid'><br>
<input type="button" id="braodcast" value='Braodcast Transaction'><br>

<p id='confirmation'> Confirmation displayed here. </p>

<script>

let client = new dsteem.Client('https://anyx.io')

function setRecovery(){
    let account = document.getElementById('account').value
    let recovery = document.getElementById('recovery').value
    let key_string = document.getElementById('key_string').value
    let key = dsteem.PrivateKey.fromString(key_string)
    let obj = {
        account_to_recover: account,
        new_recovery_account: recovery,
        extensions: []
    }
    let op1 = ['change_recovery_account', obj]
    client.broadcast.sendOperations([op1], key).then(function(result){
        document.getElementById('confirmation').innerHTML =
                account + ' changed recovery account to: ' + recovery
    })
}

document.getElementById("braodcast").onclick = setRecovery;

</script>

And I was actually really fucking surprised that I got it working so quickly considering how much trouble I've had with stuff like this in the past.

I must be getting better at reading the documentation.

In any case, you can copy/paste this code into a text file and save the extension as .html

You should be able to open the file and it automatically pops up in your default web browser.
You can then enter the three requirements (your account, new recovery account, owner key) and hit the broastcast button.

"Why would I do it this way?"

Well, you don't have to trust a frontend with your owner key.

<script src="https://unpkg.com/[email protected]^0.10.0/dist/dsteem.js"></script>

This code imports dsteem directly to your computer, which allows you to sign the transaction locally on your machine. Once the transaction is signed the client connects to @anyx's server https://anyx.io and this server broadcasts it to the network.

 let client = new dsteem.Client('https://anyx.io')

If you wanted to change your recovery account on Steem you'd connect to a Steem node instead (like 'https://api.steemit.com'

t4.png

I just now tested the above code (pasted into test.html on my desktop). It works in Chrome and in Brave.

t4.png

In fact, we can see that I've broadcasted the same transaction 6 times now, setting my alt account @smartasscards's recovery account to @v4vapid. Remember, it doesn't become official until 30 days after it's been broadcast.

Still not secure.

This takes the middleman frontend out of the equation (Peakd / Hive.io) but if your local machine was compromised (keylogger) your owner key would still be stolen. I may be doing some more work on this going forward (as most of us trust Peakd and Hive.io regardless and are more worried about basic operating system security.

t4.png

This documentation looks 'promising'.

It appears as though you can create a transaction and sign a transaction without receiving a "promise" in return. This is good because receiving a promise would imply that you connected to an outside server and got a response in the form of said promise.

t4.png

Even more promising!

Once you create the signed transaction you can send() it (aka broadcast) to the network to be confirmed by the witnesses.

So what?

Well, as we can see, the send() operation doesn't require a private key, because we already used the private key to sign in the sign() function. This implies that it is possible for us to sign a transaction with an offline device, port the public signed transaction onto an online device, and use the online device to broadcast the transaction.

This is effectively the precursor to a hardware wallet.

I have already described such a vision in great detail:

Steem Airgap Hardware Wallet

I guess I need to buy myself a Raspberry Pi and get to work!

At first, for simplicity, I would simply port the public transaction from an offline Raspberry Pi to my main computer with a flash drive. However, the ultimate goal is to turn the public transaction into a QR code that phones can scan with the camera, broadcasting the public transaction through a completely unhackable airgap.

I feel like I don't have to explain why something like this would be super badass for our platform. It would allow all users on the network to rest easy knowing it is pretty much 100% impossible for their master/owner key to get compromised by a remote hacker, as they were never exposed to the Internet at any point in time.

Conclusion

Account security is the #1 issue for many users.
At a moment like now when recovery accounts are at risk, this is the time to act.
I have a lot of work to do, but hopefully it will be worth it.

Would you bet your life on the 'fact' that Ned and/or the NSA and/or Justin Sun doesn't have access to your keys?

I wouldn't.
I technically generated my keys on Steemit.com, after all.



0
0
0.000
14 comments
avatar

I have not changed my recovered account on both chains. I never used my owner key and put it in a safe place 2 years ago.

0
0
0.000
avatar

Right but what happens if your active key gets stolen?
You need to use the owner key to change your keys.

If your owner key then gets stolen you lose your account because your recovery is bad.
Your account is not as secure as it could be.

0
0
0.000
avatar

I put a note to investigate to change my recovery account shortly. ;)

0
0
0.000
avatar

kha.jpg

Send your money my wallet, do the key 'key changey over thingy', and then I'll send it right back to you, when you're ready.
Simples.

0
0
0.000
avatar

You're talking to someone who has over 20 accounts and can make 300 more for free.

Plus I just created an Ionomy account.

:D

0
0
0.000
avatar

....yeah, but I have a Tesco club card...

0
0
0.000
avatar

I was trying the same thing and bricked my account.
I tried to change recovery, but my master key didnt work (I needed the owner key?)
then I tried to change my owner key, saved the new on top of the old (I'm an idiot) and then accepted the transaction... it told me wrong format of my owner key (has to start with 5 instead of P5) and the transaction didnt go through..

which means I've lost my owner key cuz I've overwritten it with a new which doesnt work.. :D

see you with my new account ^^

0
0
0.000
avatar

Yeah looks like the master key doesn't actually do anything except generate the other keys. Also... it seems like when you recover an account only the owner key gets changed (maybe) and you have to use the new owner key to change the active/posting with a new master key? I dun know. Still figuring it out.

0
0
0.000
avatar

When did you brick your account? I was looking for it and couldn't find it.

0
0
0.000
avatar

with "bricked" I ment, that I've overwritten my saved owner/master key with the new one, which hasnt been accepted.

Ik I'm dumb :D

0
0
0.000
avatar

If it hasn't been accepted how is it bricked?

0
0
0.000
avatar

Thanks for the info! Any thoughts on the use of Vessel to change the recovery account?

0
0
0.000
avatar

never heard of it. it's probably fine. it just requires a little trust here and there. not ideal for trustless environments

0
0
0.000