以太坊有一个非常强大的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的问题主题。这些内容如下:

  • Ethereum ecrecover signature verification and encryption
  • How can I verify a cryptographic signature that was produced by an Ethereum address key pair

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库。例如:

  • Bit-Wasp/secp256k1-php
  • phpecc
  • CryptoCurrencyPHP

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

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

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

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

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

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

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

PHP如何验证以太坊签名相关推荐

  1. 以太坊签名,验证签名, EIP712domain Permit授权并转账

    文章目录 一.Dapp 验签登录 web3.eth.accounts.recover(signtxt,sig) 具体实现过程 golang的实现 二.token EIP712Domain Domain ...

  2. 以太坊签名验签原理全面解析

    目录 签名三大作用 签名基础 不可逆计算 陷门函数 ECDSA 签名过程 ECDSA 验签过程 恢复标识符("v") 签署交易 关键词解读 EIP 191 EIP 712 ERC ...

  3. EIP712以太坊签名和验签

    EIP712旨在提高链下消息签名对链上的可用性.我们可以看到,因为节省gas以及减少链上交易的原因,采用链下消息签名的需求日益增长.现在已经被签名的消息,展示给用户的是一串难以理解的16进制的字符串, ...

  4. 以太坊完整工作原理和运行机制!

    以太坊完整工作原理和运行机制! 2018年04月28日 00:00:00 阅读数:26 作者 | Preethi Kasireddy 编译 | 老曹.Aholiab 链圈的人提起「以太坊」三个字想必是 ...

  5. 以太坊原理分析(一)以太坊工作(交易)原理

    简介 不管你们知不知道以太坊(Ethereum blockchain)是什么,但是你们大概都听说过以太坊.最近在新闻里出现过很多次,包括一些专业杂志的封面,但是如果你们对以太坊到底是什么没有一个基本的 ...

  6. 区块链扫盲之7,区块链与以太坊

    通过深入了解比特币系统我们已经知道,区块链是源自比特币的底层技术,它让我们可以无须借助任何第三方中介直接进行价值表示和价值转移,它还给数字世界带来了价值表示物--通证.区块链将使互联网从"信 ...

  7. 干货 | 以太坊的工作原理

    简介 不管你们知不知道以太坊(Ethereum blockchain)是什么,但是你们大概都听说过以太坊.最近在新闻里出现过很多次,包括一些专业杂志的封面,但是如果你们对以太坊到底是什么没有一个基本的 ...

  8. 以太坊的工作原理 程序篇

    这篇文章主要讲解以太坊的基本原理,对技术感兴趣的朋友可以看看. 原文地址:How does Ethereum work, anyway? 简介 不管你们知不知道以太坊(Ethereum blockch ...

  9. eth一张_千呼万唤的以太坊20到底启动了!你们据有32个ETH吗?

    这段工夫以太坊疯了,高歌猛进结果不负多望破了600,圈内一片欢呼忻悦.就在刚刚过去的12月1日,以太坊2.0版创世区块实现确认,千呼万唤的以太坊2.0结果到来了.当作举世数字钱银第二大佬,以太坊2.0 ...

最新文章

  1. 会话管理隐患与防御 总结
  2. CVE-2017-8890漏洞分析与利用(Root Android 7.x)
  3. git查看分支记录_git原理
  4. Ubuntu增加一个用户并给普通用户赋予root权限的方法
  5. 英特尔助力完善AI人才培养,携手微软共促地球可持续发展
  6. kvm上添加万兆网卡_烂泥:为KVM虚拟机添加网卡
  7. 【LuoguP5004】 专心OI - 跳房子
  8. 二叉树后序遍历_二叉树后序遍历非递归实现
  9. python里turtle.circle什么意思_Python turtle.circle方法代碼示例
  10. 易懂的比特币工作机理详解
  11. 和quicklook相似的软件_细数软件推荐上万热度出现比例较高的10款软件,看看谁出现最多...
  12. Android小项目--2048小游戏
  13. 天线基础与HFSS天线设计流程
  14. 5种常见的网络欺骗方式
  15. 百度云网盘高速通道加速破解版 去广告纯净版干净云
  16. CAD中PDF转DWG
  17. android图片模糊效果,Android下实现高效的模糊效果
  18. match和search的区别
  19. 深度学习的开胃菜——常用的机器学习知识梳理
  20. 工具-安装redis和安装redis客户端

热门文章

  1. python课程与c+课程有什么不同-南通渡课少儿编程:python和C的区别是什么?
  2. 廖雪峰python教程视频-为什么看不懂廖雪峰的Python学习教程?
  3. python爬虫实例-python3.7简单的爬虫实例详解
  4. python里面temp是啥-python temp file:如何打开多次临时文件?
  5. 使用OpenVINO ToolKit 实时推断
  6. DL-3利用MNIST搭建神经网络模型(三种方法):1.用CNN 2.用CNN+RNN 3.用自编码网络autoencoder
  7. UVa 12012 - Detection of Extraterrestrial(hash)
  8. Scikit-learn环境的搭建
  9. LeetCode Single Number
  10. linux ubuntu 虚拟机中配置samba的实现文件共享的方法