在区块链上确保2FA安全

SMS消息是最流行的两因素身份验证(2FA)方法。 银行,电子和加密钱包,邮箱和各种服务都使用它。 该方法的用户数接近100%

我这样的事件爆发是令人发指的,因为这种方法是不安全的。 从移动时代开始就将号码从一张SIM卡重新分配给另一张-这就是丢失SIM卡后如何恢复号码的方式。 实现了“数字货币断奶专家”:可以在欺诈性方案中使用“覆盖SIM卡”选项。 毕竟,控制SIM卡的人可以管理其他人的网上银行,电子钱包,甚至是加密货币。 您还可以使用欺诈或伪造文件贿赂电信员工,从而接管他人的电话号码。



已发现成千上万次SIM交换事件-这就是所谓的欺诈方案。 灾难的严重性表明,世界很快将通过SMS放弃2FA。 但这并没有发生- 研究表明,选择2FA方法的不是用户,而是服务所有者。

我们建议使用安全的2FA方法,并通过区块链传递一次性代码,并告诉您如何将其连接到服务所有者。

账单上百万


根据伦敦警方的说法,2019年,SIM卡掉期欺诈增加了63%,攻击者的“平均支票”为4,000英镑。 我没有在俄罗斯找到统计信息,但我认为情况甚至更糟。

比特币企业家Joby Weeks 报道说 ,SIM卡交换用于窃取流行的Twitter,Instagram,Facebook,VK帐户,银行帐户以及最近进入的加密货币。 自2016年以来,在媒体报道中已经出现了备受瞩目的利用SIM卡交换盗窃加密货币的案例; 在2019年达到了真正的高峰。

5月,密歇根州东部地区的美国检察官起诉了 9名19至26岁的年轻人:据称他们是一个名为“社区”的黑客团伙的成员。 该团伙被控进行七次掉期攻击,因此黑客盗用了价值超过240万美元的加密货币。 4月,来自加利福尼亚的一名学生乔尔·奥尔蒂斯(Joel Ortiz)因更换SIM卡而被判入狱10年; 750万美元的加密货币成为了它的猎物。


乔尔·奥尔蒂斯(Joel Ortiz)在大学新闻发布会上的照片。 两年后,他将因网络欺诈而被拘留。

SIM卡交换的原理


交换意味着交换。 在所有这些方案中,犯罪分子通常通过重新发行SIM卡来分配受害者的电话号码,然后使用该电话号码来重置密码。 理论上,典型的SIM交换如下所示:

  1. 情报。 欺诈者找出受害者的个人数据:姓名和电话。 它们可以在开放源代码(社交网络,朋友)中找到,也可以从同伙(移动运营商的雇员)获得。
  2. 阻塞。 受害者的SIM卡已停用; 为此,只需致电提供商的技术支持,报告电话号码并说电话已丢失。
  3. 捕获号码并将其转移到您的SIM卡中。 通常,这也可以通过电信公司的帮凶或伪造文件来完成。

在现实生活中,情况仍然更为严峻。 攻击者选择一个受害者,然后每天监控电话的位置-一个有关用户已切换到漫游的信息请求的费用为1-2美分。 SIM卡拥有者出国后,便会与通讯沙龙的经理达成协议,签发新的SIM卡。 它的成本约为50美元(我发现信息-在不同的国家和不同的运营商,其价格从20美元到100美元不等),而经理在最坏的情况下将被解雇-这不承担任何责任。

现在,所有入侵者都将收到所有短信,而手机的所有者将无法对其进行任何操作-他在国外。 然后,恶棍可以访问受害者的所有帐户,并且可以根据需要更改密码。

可能返还被盗的货物


银行有时会去找受害者,并从他们的账户中提取转账。 因此,即使没有发现违法者,也可以归还法定货币。 但是,使用加密货币钱包,无论在技术上还是在法律上,一切都变得更加复杂。 到目前为止,还没有交易所/钱包为交换受害者支付了补偿。

如果受害者想在法庭上为自己的钱辩护,那么他们就指责经营者:他创造了从账户中盗窃金钱的条件。 这正是迈克尔·特平(Michael Turpin)所做的 ,他因掉期而损失了2.24亿美元,现在他在起诉AT&T电信公司。



到目前为止,还没有州制定任何法律上保护加密货币所有者的工作计划。 无法为您的资本提供保险或就其损失获得赔偿。 因此,防止交换攻击比对抗其后果更容易。 最明显的方法是对2FA使用更可靠的“第二因素”。

SIM卡交换不是通过SMS唯一的2FA问题


从技术角度来看,SMS中的确认代码也不安全。 由于信令系统7(SS7)中存在致命漏洞,因此可以截获消息。 SMS的2FA被正式确认为不安全(美国国家标准技术研究院在其《 数字认证指南》中对此进行了说明)。

而且,2FA的出现通常会激发用户虚假的安全感,并且他选择了一个更简单的密码。 因此,这种身份验证并不复杂,但是可以使攻击者更容易访问该帐户。

而且,SMS经常会延迟很长时间甚至根本不会延迟。

其他2FA方法


当然,在智能手机和SMS上,光线并未收敛。 还有其他2FA方法。 例如,一次TAN编码:该方法是原始方法,但是可以工作-在某些银行中仍在使用。 有些系统使用生物特征数据:指纹,视网膜扫描。 在方便性,可靠性和价格方面,另一个似乎合理折衷的选择是2FA的特殊应用:RSA令牌,Google身份验证器。 并且有物理键和其他方法。

从理论上讲,一切看起来都是逻辑可靠的。 但是实际上,现代2FA解决方案存在问题,因此,现实与期望有所不同。

根据该研究 ,使用2FA原则上是一种不便,并且通过SMS进行2FA的普及可以通过“与其他方法相比不那么麻烦”来解释-接收一次性代码对于用户而言是可以理解的。

许多2FA方法用户担心会丢失访问权限。 物理密钥或TAN密码列表可能会丢失或被盗。 我个人使用Google Authenticator的经历很消极。 我使用该应用程序的第一部智能手机坏了-请评估我恢复帐户访问权的努力。 另一个问题是过渡到新设备。 出于安全方面的考虑,Google Authenticator无法导出(如果可以导出密钥,那将提供什么样的安全性?)。 一旦我手动转移了密钥,然后决定将旧的智能手机放在架子上的盒子里就容易了。

2FA方法应为:

  • 安全-只有您有权访问自己的帐户,而不是攻击者
  • 可靠-您随时可以访问自己的帐户
  • 方便且负担得起-使用2FA非常简单,只需最少的时间
  • 便宜的

我们认为区块链是正确的解决方案。

在区块链上使用2FA


对于用户而言,区块链上的2FA看起来与通过短信接收一次性代码相同。 唯一的区别在于交付渠道。 获取2FA代码的方式取决于区块链提供的内容。 在我们的项目中(信息在我的个人资料中),这是一个Web应用程序,Tor,iOS,Android,Linux,Windows,MacOS。

该服务生成一次性代码并将其发送到区块链上的Messenger。 此外,根据经典:用户在服务界面中输入接收到的代码并登录。



在文章《分散的Messenger如何在区块链上工作》中,我写道,区块链可确保消息传递的安全性和隐私性。 关于发送2FA代码的主题,我将重点介绍:

  • 一键创建帐户-没有电话或电子邮件。
  • 所有带有2FA代码的消息均被加密为“端到端曲线” 25519xsalsa20poly1305。
  • 不包括MITM攻击-每个带有2FA代码的消息都是区块链上的事务,并由Ed25519 EdDSA签名。
  • 带有2FA代码的消息将落入其块中。 块的顺序和时间戳无法确定,因此消息的顺序也无法确定。
  • 没有中央结构可以检查消息的“真实性”。 这是由基于共识的分布式节点系统完成的,它属于用户。
  • 无法禁用-无法阻止帐户,并且可以删除邮件。
  • 随时从任何设备访问2FA代码。
  • 带有2FA代码的交货确认消息。 发送一次性密码的服务可以确定已将其交付。 没有“再次提交”按钮。

为了与其他2FA方法进行比较,我编译了一个表:



用户在区块链Messenger中接收一个帐户以在一秒钟内接收代码-仅使用密码输入。 因此,应用方法可能不同:您可以使用一个帐户获取所有服务的代码,也可以为每个服务创建一个单独的帐户。

还有一个缺点-一个帐户必须至少有一笔交易。 为了使用户收到带有代码的加密消息,您需要知道他的公钥,并且他只有在进行第一次交易时才会出现在区块链中。 我们这样走了:他们给了我们机会在我们的钱包里获得免费代币。 但是,一种更正确的解决方案是将帐户命名为公共密钥。 (作为比较,我们的帐号U1467838112172792705是公钥cc1ca549413b942029c4742a6e6ed69767c325f8d989f7e4b71ad82a164c2ada的派生工具。对于Messenger来说,这更方便易读,但对于发送系统2FA代码而言)。 我认为将来会有人做出这样的决定,并将“便利性和可及性”转移到绿色区域。

发送2FA代码的成本非常低-0.001 ADM,现在为0.00001 USD。 同样,您可以提高区块链并使价格为零。

如何将区块链上的2FA连接到您的服务


我希望我能够引起一些读者的兴趣,以将区块链授权添加到他们的服务中。

我将使用我们的Messenger的示例来告诉您如何执行此操作,以此类推,您可以使用另一个区块链。 在2FA演示应用程序中,我们使用postgresql10来存储帐户信息。

连接步骤:

  1. 在区块链上创建一个帐户,您将从该帐户发送2FA代码。 您将收到一个密码删除密码,该密码用作私钥,用于使用代码加密消息并签署交易。
  2. 将脚本添加到服务器以生成2FA代码。 如果您已将其他2FA方法与一次性密码传递一起使用,则此步骤已经完成。
  3. 将脚本添加到服务器以将代码发送给区块链Messenger中的用户。
  4. 创建用于发送和输入2FA代码的用户界面。 如果您已将其他2FA方法与一次性密码传递一起使用,则此步骤已经完成。

1创建一个帐户

在区块链中创建账户是生成私钥,公钥以及从中派生的账户地址。



首先,生成密码短语BIP39,从中考虑SHA-256哈希。 散列用于生成ks私钥和kp公钥。 从具有相同SHA-256的公钥(具有反演)中,获得区块链中的地址。

如果您想每次从一个新帐户发送2FA代码,则需要将用于创建帐户的代码添加到服务器:

import Mnemonic from 'bitcore-mnemonic' this.passphrase = new Mnemonic(Mnemonic.Words.ENGLISH).toString() … import * as bip39 from 'bip39' import crypto from 'crypto' adamant.createPassphraseHash = function (passphrase) { const seedHex = bip39.mnemonicToSeedSync(passphrase).toString('hex') return crypto.createHash('sha256').update(seedHex, 'hex').digest() } … import sodium from 'sodium-browserify-tweetnacl' adamant.makeKeypair = function (hash) { var keypair = sodium.crypto_sign_seed_keypair(hash) return { publicKey: keypair.publicKey, privateKey: keypair.secretKey } } … import crypto from 'crypto' adamant.getAddressFromPublicKey = function (publicKey) { const publicKeyHash = crypto.createHash('sha256').update(publicKey, 'hex').digest() const temp = Buffer.alloc(8) for (var i = 0; i < 8; i++) { temp[i] = publicKeyHash[7 - i] } return 'U' + bignum.fromBuffer(temp).toString() } 

在演示应用程序中,我们对其进行了简化-在Web应用程序中创建了一个帐户,然后从中发送代码。 在大多数情况下,这对用户来说更方便:他知道该服务从特定帐户发送2FA代码并可以对其进行命名。



2代2FA代码

需要为每个用户登录生成2FA代码。 我们使用speakeasy库,但您可以选择其他任何库。

 const hotp = speakeasy.hotp({ counter, secret: account.seSecretAscii, }); 

验证用户输入的用户2FA代码:

 se2faVerified = speakeasy.hotp.verify({ counter: this.seCounter, secret: this.seSecretAscii, token: hotp, }); 

3提交2FA代码

您可以使用区块链节点API,JS API库或控制台来发送2FA代码。 在此示例中,我们使用控制台-这是命令行界面,该实用程序可简化与区块链的交互。 要发送带有2FA代码的消息,您需要使用控制台的send message命令。

 const util = require('util'); const exec = util.promisify(require('child_process').exec); … const command = `adm send message ${adamantAddress} "2FA code: ${hotp}"`; let { error, stdout, stderr } = await exec(command); 

发送消息的另一种方法是使用JS API库中的send方法。

4个用户界面

需要给用户输入2FA代码的机会,这可以通过多种方式完成,具体取决于应用程序的平台。 在我们的示例中,这是Vue。



可以在GitHub上查看二元授权在区块链上的演示应用程序的源代码。 自述文件的实时演示中有一个链接可以尝试。

Source: https://habr.com/ru/post/zh-CN476090/


All Articles