专栏首页极客编程PHP如何通过编程在服务端验证以太坊签名

PHP如何通过编程在服务端验证以太坊签名

以太坊有一个非常强大的JavaScript生态系统。有一些很棒的开源项目,比如ethereumjs-util,它提供了一个用以太坊帐户签名的即插即用功能。

JavaScript的一个缺点是,在许多领域,它带来了安全问题。一个这样的安全风险是显而易见,这是由于我努力在EthTools.com上实现持久性认证(仍然是一个正在进行的被警告了的工作)。

利用开源项目(如ethereumjs-util)来签署任意的数据消息是相当容易的。然而,不容易的是告诉服务器有人已经成功地验证了某帐号的所有权。

当然这也不是绝对正确的,你也可以很容易做到这一点。简单地构建一个简单的API端点,并在成功认证后向其发出请求。

真正的问题是,创建一个“假”请求并将其发送到上述(易于识别 - 只需在控制台中查看)端点非常容易。 我可以轻松发出请求,说我已经验证了任何帐户的所有权。

凭借尖端技术……特别是处理“真实价值”的技术,尤其重要的是安全性体现出了它应有的重要性并被重视,特别是在历史上出现各种被利用的攻击的情况下。

而且即使是在初期,以太坊也吸引了最优秀的人——那些知道在做什么的人。如果有安全漏洞,有人会找到它。

现在。。虽然可以确保AJAX请求和伪造更难,但几乎不可能使交易100%的安全。我需要另一种方式。

我最终解决的方法是选择最简单的服务器端认证方式。

对每个人交易都是可视化的

在客户端中与区块链交互的一件大事是,在任何情况下,任何人都能清楚地看到你在做什么。他们可以自信地知道你没有把他们的私人钥匙发送给别人。怎样?他们可以查看控制台并查看每一个发出的请求。

如果一个服务在任何地方POSTing我的私钥,我会非常担心。

在我们实现的认证流中,用户可以看到我们没有在任何地方发送任何数据——所有的东西都是在客户端中完成的。

遗憾的是,我的身份验证方案中确实需要POSTing数据。但也不用担心(有些人可能不同意)。

我们POST身份验证的公钥到我们的API端点。虽然你不能用服务器上的公钥来验证我们所做的事情,但我们并没有用你的公钥做任何恶作剧——这就是为什么它是公开的。

在服务器上,我们使用提交的公钥来验证提交的签名是由具有相应私钥信息的人创建的。这里要明确指出,我们不知道你的私钥,但椭圆曲线加密允许我们通过简单地使用公钥来验证签名是否是使用它创建的。

在ethereumjs-util和solidity中,ecrecover方法是前提,除非这些工作分别在客户端和区块链中。

以太坊论坛上,chriseth给出了ecrecover的以下有用解释:

ecrecover的思想是,可以计算对应于用于创建ECDSA签名的私钥的公钥,这两个额外的字节通常是由签名提供的。签名本身是椭圆曲线点R和S的两个(编码),而V是恢复公钥所需的两个附加位。

这也解释了为什么返回类型是地址:它返回对应于恢复的公钥(即其sha3/keccak的哈希)的地址。这意味着要实际验证签名,检查返回的地址是否等于相应的私钥应该已经签署哈希的那个地址。

我们希望在服务器上有相同的功能。

注意:Solidity的ecrecover返回一个地址,而ethereumjs-utils的ecrecover返回一个公钥。

注:研究期间,我发现了一些有趣的StackExchange的问题主题。这些内容如下:

web3.js API文档还提供了一些关于ecrecover的参数的见解:

After the hex prefix, characters correspond to ECDSA values like this:

r = signature[0:64]
s = signature[64:128]
v = signature[128:130]

Note that if you are using ecrecover, v will be either "00" or "01". As a result, in order to use this value, you will have to parse it to an integer and then add 27. This will result in either a 27 or a 28.

PHP中怎么做

[EthTools.com]是建立在Phalcon PHP框架之上的。

没有真正意义上的以太坊PHP社区,PHP在处理数值表示方面有其缺点。

当然,椭圆曲线密码的问题是极其复杂的,而我对它也缺乏已经掌握的可用知识。

在大量的资料查询研究和大量的开发调试之后,我成功地实现了PHP中的ecrecover功能。

虽然我知道如何做到这一点,我写了一些“笔记”,我整理和包含在下面的内容,希望能帮助别人了解正确的方向。

我的行动逻辑是使用ethereumjs-util,使用已知的以太坊私钥签署交易。然后,我会模仿PHP中的ecrecover方法的代码路径,然后像宏播放一样执行,直到从签名返回的输出公共密钥与原始签名帐户匹配。

所以…

在Node中,缓存 Buffers 是无符号8位整数的数组。 digits 是它们的10进制(十进制)表示。

8位就会有2^8=255个十进制选项。这些整数是来自UTF-8字符集的字符的数字编码表示。

Node利用这些缓存来进行这些计算所需的排序的数据操作。

在服务器上,我们有不同的字符串(消息哈希和签名),但是PHP不知道这些字符串中的字节是base 16 numerical表示(十六进制)。

每个字符都是一个“小写”,它需要4个字节来表示(允许十六进制字符是0—9和A—F)。

这样,8位数据是两个十六进制字符。

在Node中,将字符串“61BF09”转换为一个buffer,通过将两个小写的集合转换成它的十进制形式。

  • 61转成97
  • bf转成191
  • 09转成9

要在PHP中执行等效,我们执行如下的操作:

$r_byte_array = unpack('C*', hex2bin($r));

我们调用hex2bin,它将十六进制字符串(不含0x)转换为二进制表示(base 2)。通过调用这个方法,我们隐式地说明初始格式是十六进制。

unpack然后将字符串转换为代码中的数组——我们的Buffer等价物。

最初PHP只是认为字符串是UTF-8。如果我们不先调用hex2bin,第一个int是54,效果是这样:

这是因为unpack只是将UTF8中的第一个字节(54)转换成二进制代码(6),64个字符=64个代码点。

当我们告诉unpack我们处理十六进制时,它将每个两个字节的十六进制集合(每个代表4位数据的字符)转换为它的十进制表示。61(0x61)变为97。我们的64个字节十六进制字符串变成32个8位整数,效果是这样:

你可以通过使用这个转换器来看这些不同的表示。

现在,你就有一个符合要求并且已经格式化了的消息哈希和签名表示,“你可以作弊了”。

我比较懒和喜欢自做聪明。也就是说,让我试图充分理解、欣赏和实施secp256k1椭圆曲线是根本不会发生的。此外…何苦?这是一个不需要重新发明的轮子。

我发现了一些与secp256k1有关的php库。例如:

我最终使用了所有三个库的组合,我喜欢知道我在使用什么,并且基本上(至少)理解我正在向服务器推送什么。上面的库是相当丰富的、复杂的,我只是简单提取我需要的相对简单的功能。

在花了大量的时间来了解我正在做的事情之后,我终于成功地实现了我想要达到的目标——我已经成功地验证了以太坊客户端中创建的签名是来自我的一个特定的私钥。

当我第一次爬进这个rabbit hole的时候,我会继续实施我所想到的功能。

注意事项。2018年又我写了第二篇文章,详细介绍了我如何验证PHP先前签署的消息的有效性。(注:后面也会翻译给大家)

如果大家在学习用php开发以太坊那我们推荐这个教程:

php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。

汇智网原创翻译,转载请标明出处。这里是原文

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Blockchain和Tangle哪一个是未来?

    2017年是加密货币热潮令人难忘的一年。从那时起到现在世界没有任何改变,但今天我们对加密货币仍然很兴奋。乐观主义者认为,比特币将从根本上改变世界各地的支付,经济...

    笔阁
  • 如何开发创建ERC20以太坊代币

    可以把ERC20简单理解成以太坊上的代币协议,所有基于以太坊开发的代币合约都遵守这个协议。遵守这些协议的代币我们可以认为是标准化的代币,而标准化带来的好处是兼容...

    笔阁
  • 用Java为Hyperledger Fabric(超级账本)开发区块链链代码智能合约之编写链代码程序

    在上一节中,您已经熟悉了如何构建、运行、部署和调用链代码,但尚未编写任何 Java 代码。

    笔阁
  • Kubernetes 1.9发布:Apps Workloads通用版本与生态系统扩展

    我们很高兴在今年之内进行第四次——也是最后一次版本更新公告,即Kubernetes 1.9的诞生!

    Debian社区
  • 加速布局无服务器生态,腾讯云与Serverless.com达成全球战略合作

    在云计算技术领域,“Serverless(无服务器)”作为一种新型的软件设计架构正在快速崛起。作为继虚拟机、容器后的第三代通用计算平台,Serverless技...

    腾讯云serverless团队
  • 腾讯云 Serverless Framework 正式发布会

    2020 年 4 月 21 日(周二)14:00,腾讯云 Serverless Framework 将正式召开线上发布会,这是由腾讯云提供的专为中国开发人员定...

    腾讯云serverless团队
  • 面向AI开发公司的几大机器学习框架(2020年版)

    事实上,人工智能技术正日益使我们的生活更简单。如果我们想一下,现在每个部件或组件都附有某种机器学习工具,基本上不需要人的干预即可使用。

    Lemon黄
  • python三方库之requests-快速上手

    其他请求接口与HTTP请求类型一致,如PUT, DELETE, HEAD, OPTIONS等。

    枇杷李子橙橘柚
  • 如何防止softmax函数上溢出(overflow)和下溢出(underflow)

    《Deep Learning》(Ian Goodfellow & Yoshua Bengio & Aaron Courville)第四章「数值计算」中,谈到了上...

    zenRRan
  • Java 基础(六)——集合源码解析 Queue

    Queue继承自 Collection,我们先来看看类结构吧,代码量比较少,我直接贴代码了。

    蜻蜓队长

扫码关注云+社区

领取腾讯云代金券