关于Steemit的密码和私钥关系

in #cn7 years ago (edited)

备注:文中 Steem 指的是区块链,Steemit 指的是 <steemit.com> 网站,请注意区分。

前因

这一切的一切还要从最近帮朋友注册 Steemit 账号说起。之前我使用 Steem Python 来注册新用户,密码是用 https://v2.steemconnect.com/accounts/create 生成。前几天帮朋友注册的时候,发现 steem-python 注册用户有异常报错,于是就换成了 Vessel 注册新用户了,并且总结了一篇 教程

由于使用 Vessel 注册用户的时候,我看到有一个 Generate new private_keys 的按钮,就在想这个是不是也能生成密码呢,就试了下,发现并不能,只能生成脑钱包密码和私钥。

于是想能不能随便拿个私钥来做密码,毕竟私钥也是个随机字符串,理论上讲当做密码也是没问题的,同时我也好奇 Steem 能不能不用任意字符串做密码,而不是那个 P 开头的字符串。

第二天为了试验 Steem Python 是否好用了的时候,就顺便拿了一个 Vessel 生成的 Owner Private Key 作为密码。注册成功了,但是在 Steemit.com 登陆的时候,却提示我密码错误。

这是怎么回事?!瞬间就慌了,以为3个币的注册费要白花。赶紧用 Steem Python 输出这个账户的 Posting Private Key 尝试登陆,成功了,又导出了 Active Private Key 试了试,也可以。

也就是说,我现在拥有除了改密码以外的所有功能。这让我很不爽。又试了几遍不行后,感觉自己也是认栽了,就把 Vessel 生成私钥的窗口给关了。注册用做密码的那个私钥,我是一个备份都没有留,太大意了!观察了一会,发现原来 Steemit 网站的登陆密码其实是一个私钥开头加上了一个 P,而这个时候刚才的 Vessel 窗口都让我关了,也没法试一试,是不是就是我用的那个私钥开头加了一个 P。真是太恨自己的手快了。。。

又过了一天,感觉这个事不能就这样结束了,于是又重新走了一遍这个流程,又用私钥注册了一个账户,分别用这个私钥和这个私钥加 P 登陆,结果还是登陆失败。

13591518741831_.pic.jpg

过程

我决定要从源码入手了,看看到底发生了什么?!

先看了下 Steem Python 的代码,在 https://github.com/steemit/steem-python/blob/master/steem/commit.py#L511https://github.com/Netherdrake/steem-python/blob/master/steembase/account.py#L24 这两个位置找到了注册的时候私钥是如何生成的。

这里我把关键代码摘出来了

posting_key = PasswordKey(account_name, password, role="posting")
active_key = PasswordKey(account_name, password, role="active")
owner_key = PasswordKey(account_name, password, role="owner")
memo_key = PasswordKey(account_name, password, role="memo")

class PasswordKey(object):
    def __init__(self, account, password, role="active"):
        self.account = account
        self.role = role
        self.password = password

    def get_private(self):
        a = bytes(self.account +
                  self.role +
                  self.password, 'utf8')
        s = hashlib.sha256(a).digest()
        return PrivateKey(hexlify(s).decode('ascii'))

....省略后面的代码

原来我们设置的登陆密码只是一个Salt,所有的私钥是通过把 usernamerolepassword 连接后哈希出来的。

如果按照这个逻辑,我用私钥字符串做密码并不应该出现密码错误的情况。

为了验证这个推断,我用 Steem Python 库中的方法进行了验证,如下:

通过库中的方法,我成功导出了 tinyfish 这个账号的 Owner Private Key,也就是说,Steemit 的密码其实可以设置为任意字符串的,这个密码只是一个 Salt ,只是为了方便我们记忆,因为在 Steem 链上只有公钥和私钥,而一个账户下最少拥有了3对公私钥,通过密码这种形式来简化记忆的难度。

那么既然 Steem Python 的代码没有问题,那么鬼一定就出在 Steemit 网站上了,难道因为我用的是私钥,触发了网站的某个逻辑,进而导致我进入了错误的登陆流程?

为了验证我的这个推断,继续去翻 condenser 的代码。最终在这里找到了答案,https://github.com/steemit/condenser/blob/master/src/app/redux/UserSaga.js#L198

我摘出来了重要部分

    try {
        const private_key = PrivateKey.fromWif(password);
        login_wif_owner_pubkey = private_key.toPublicKey().toString();
        private_keys = fromJS({
            posting_private: isRole('posting', () => private_key),
            active_private: isRole('active', () => private_key),
            memo_private: private_key,
        });
    } catch (e) {
        // Password (non wif)
        login_owner_pubkey = PrivateKey.fromSeed(username + 'owner' + password)
            .toPublicKey()
            .toString();
        private_keys = fromJS({
            posting_private: isRole('posting', () =>
                PrivateKey.fromSeed(username + 'posting' + password)
            ),
            active_private: isRole('active', () =>
                PrivateKey.fromSeed(username + 'active' + password)
            ),
            memo_private: PrivateKey.fromSeed(username + 'memo' + password),
        });
    }

看代码也就是只有通过 PrivateKey.fromWif 这个方法拿不到 private_key 的时候,应该会有异常抛出,然后才进入到 catch 的流程中,也就是我们用密码登陆的流程。

所以我用私钥做密码注册的小号登陆失败的原因,就是因为网站直接把我的密码当做私钥用了,那肯定是要报错了!!!

在知道原因后,我可以用 posting private key 登陆网站,然后修改密码的时候,用从 Steem Python 中读取出来的 Owner private key 完成密码修改。只是可惜了我第一个小号的密码没有保存,再次后悔若干分钟。可能唯一的解决方法就是暴力破解了。。。。

总结

  • 请不要使用生成的私钥字符串作为你的登陆密码!
  • 无论用什么生成器生成密码,请一定要先存好!
  • 修改密码后,记得保存新生成的各个私钥!

感谢你的阅读,我是一个见证人,欢迎通过 SteemConnect 来给我投票,或者打开 https://steemit.com/~witnesses 页面,输入 ety001 进行投票。

2.gif

Thank you for reading. I'm a witness. I would really appreciate your witness vote! You can vote by SteemConnect. Or open https://steemit.com/~witnesses page, input ety001 to vote.

2.gif

Sort:  

我同样遇到了这个问题,我注册了两个小号登陆显示密码错误,我还以为我抄错了。

可惜现在我早就把备份的密码丢掉了。

我那个@ety001.bot 也是把密码扔了。。。还好留着post key和active key,还能用。
等以后有机会写个暴力破解的程序,看看有没有机会跑出来密码吧😂

我发现登陆不上,以为是自己抄错密码,试了几次就放弃了,现在我连账号名都忘记了,悲催。

你是用什么注册的?我当时使用的是steempy注册的,所以注册成功后,自动保存了posting key和 active key到本地钱包里了。

https://v2.steemconnect.com/accounts/create
这里注册的,2个账号白白浪费了6个steem

那没有招了。

虽然涨了很多知识还是没有全部看懂。active private key是怎么导出的?这是第一个没看明白的地方

使用 Steem Python 注册用户后,会自动把新用户加入到 Steem Python 的本地钱包里,不过只是把 postingactive 这两个权限加入到钱包里了, owner 的私钥并没有加进来。

正因为新注册的用户自动加入了钱包,所以才能用 Steem Python 的命令打印出来私钥,

$ steempy getkey <公钥>

看着很高级,但表示没有看懂。

不过研究的精神是看懂了,过年时间这么闲真的好吗?

说出你的疑点~

不是闲,而是弄不出来睡不着觉。。。😂

没有研究过密码这些,所以看不懂,不是你表达的问题,是我水平的问题。

只要使用 用户名 + Owner Private Key 登录steemit, 它就提示你,说此密码绑定 owner key了,问你是否更改密码

恩,因为系统判断了提交的密码是私钥还是普通的密码,如果是私钥的话,是哪一种权限的私钥。

会编程就是牛!我只会用邮箱注册,其它都不会。貌似你是我看到的第一个中文区的见证人。厉害!

其实会编程也有苦恼,就是什么东西见了,都会在想这个功能是怎么做出来的🤣。。

另外我不是中文区第一个见证人,貌似大神 @abit 是第一个,另外 @skenan 也是比我早的见证人。欢迎给他们也投上一票~

中文区之外的见证人看到了几个,上面的两位没打过交道,有机会再聊。除了上帝之外,没有别的神,基督徒这样跟我讲。

最后这句 66666

Congratulations! This post has been upvoted from the communal account, @minnowsupport, by ETY001 from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, theprophet0, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows. Please find us at the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.

If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: 50SP, 100SP, 250SP, 500SP, 1000SP, 5000SP.
Be sure to leave at least 50SP undelegated on your account.

大神,help。我自五月注册登录以来,读了关于密码安全的帖子,认真备份了主密码和owner秘钥。中途几次都是直接拿owner 秘钥登录的,后来为了更安全又因新人没什么需要动用的资产,就一直用posting 秘钥登录发帖。可昨晚上下载了partiko需要其他私钥确权,我弄到现在也没登上去,不知道问题出在哪里。我也试了恢复账号,单系统显示账户的主权并没有变更。如果说我备份的秘钥是错的,那之前登的若干次又怎么登上去了呢?现在我的账户除了posting key能成功登陆,其他都显示密码错误。百思不得其解,搜到了您的帖子,是以,求指引。

portiko没有用过,估计你得拿active的私钥登陆吧,可以问一下partiko官方的人。

Partiko只是app的名字,实际上它是通过steemconnect登录的。因为登不上,我就拿之前备份的私钥回来网页版登录,才发现统统登不上了。555555。如果不是因为想用移动端,我可能再过几个月才会发现这个令人心慌的事实。

你的意思是你之前备份的私钥出问题了?你之前刚注册的时候,有没有用你备份的私钥登陆尝试过?如果你注册后一直用的posting的私钥登陆,那么很可能你之前备份的密码和私钥都有问题吧。

恰恰我七月之前都是用备份的owner key登录的,只有七月后开始用posting key登录。 我也没有改过密码呀。

肯定是有哪个环节有问题,不过我是不知道了。。。

哎。就当一个树洞吧。我已新申请账号了。