本文编写了一个小例子诠释了EOS是如何对数据签名与校验的,通过本文可以理解了签名的重要性和数据的不可篡改性。

  系统: ubuntu  版本为EOS1.1.1

注:因为本文的程序是把EOS里面的钱包和fc工具的代码全部提取出来编译的,这个过程相对复杂本文不做解释,这里只注重本文的内容,但我的示例代码是来自于此用例的片段。

一.测试代码

std::string dig_str("test");

public_key_type  pubk(std::string("EOS62M5kVouCEU31xP736Txb4pe82FoncprqevPuagE6boCLxwsC8"));
import_key("5KT27tqC9YgfEyqD61EjCFRz7QXTz8XrYadzZ8LAGt7HVovUHnT");

fc::crypto::signature sig_stru = sign_digest(dig, pubk);

unsigned char arr_sign[];
unsigned char arr_pubkey[]; memset(arr_sign, , sizeof(arr_sign));
memset(arr_pubkey, , sizeof(arr_pubkey)); fc::datastream<const unsigned char*> ds_sign( arr_sign, );
fc::raw::pack( ds_sign, sig_stru);
int siglen = ds_sign.tellp();

std::cout << std::string(dig) << std::endl;
  std::cout << std::endl;


std::cout << std::string(sig_stru) << std::endl;
  std::cout << std::endl;

fc::datastream<const unsigned char*> ds_pub( arr_pubkey,  );
for(int i = ; i < siglen; ++i) {
printf("%02x", arr_sign[i]);
} std::cout << std::endl; fc::raw::pack( ds_pub, pubk);
int publen=ds_pub.tellp(); for(int i = ; i < publen; ++i) {
printf("%02x", arr_pubkey[i]);
} std::cout << std::endl; assert_recover_key( dig, arr_sign , siglen,arr_pubkey, publen );

代码运行的结果如下:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

SIG_K1_KkSbKuDSV7x87FeexJ3goinHsd3MhPBCH91MRqhyS3Z7H1v4HtUZoJc6AkgYWW5mEan7UbdmDAzDpCzUwheDPxRxtzuD8s

002077f62e26587bd9345c61cf1904f048b1e2cd252acae79d3c1e6f48a4aef9bd03778ae7498014e9207e35117cf79920b2e31becb7e24d6c09ebeaf184c956c81c

000295898b10fe9f5f056ed09e334e8e768e42cc16c1a2e02565de6d57b5e25cfd55

二.代码分析

1.数据发送端

首先,我们对字符串"test"形成摘要,摘要转换成字符串为:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

然后再对摘要使用私匙签名,转换成字符串形式输出如下:

SIG_K1_KkSbKuDSV7x87FeexJ3goinHsd3MhPBCH91MRqhyS3Z7H1v4HtUZoJc6AkgYWW5mEan7UbdmDAzDpCzUwheDPxRxtzuD8s

但实际上上面的数据存在于arr_sign中的数据(对应的datastream也可),我这里按字节打印成十六进制是如下格式的:

002077f62e26587bd9345c61cf1904f048b1e2cd252acae79d3c1e6f48a4aef9bd03778ae7498014e9207e35117cf79920b2e31becb7e24d6c09ebeaf184c956c81c

到这里我们得到了数据test内容的签名,那么发送数据方就可以使用明文test再加上签名进行发送给对端,签名一般使用十六进制。

2.数据接收端

在上面的用例中,我们直接调用EOS即assert_recover_key就可得到验证,那么如何是在合约中呢?

如果数据在合约中验证,我们需要三个字段:发送的明文+签名+用户公匙

明文就是test,签名就是 002077f62e26587bd9345c61cf1904f048b1e2cd252acae79d3c1e6f48a4aef9bd03778ae7498014e9207e35117cf79920b2e31becb7e24d6c09ebeaf184c956c81c

公匙就是000295898b10fe9f5f056ed09e334e8e768e42cc16c1a2e02565de6d57b5e25cfd55,而不是EOS62M5kVouCEU31xP736Txb4pe82FoncprqevPuagE6boCLxwsC8,其实这么说不准确,只是前者是以十六进制体现出来的。

现在接收端收到的内容是:test + 002077f62e26587bd9345c61cf1904f048b1e2cd252acae79d3c1e6f48a4aef9bd03778ae7498014e9207e35117cf79920b2e31becb7e24d6c09ebeaf184c956c81c

(用户的公匙理论上是接收方本来就知道的)

那么现在合约中代码就只需要转换一下格式即可:

 struct sig_hash_key {
transaction_id_type dig;
public_key pk;
signature sig;
}; sig_hash_key sh;
public_key pk; sha256(const_cast<char*>(userdata.data()),userdata.length(), &sh.dig); from_hex( sig, (char*)sh.sig.data, sig.length() );
from_hex( pubk, sh.pk.data, pubk.length()); assert_recover_key( &sh.dig, (const char*)&sh.sig, sizeof(sh.sig), sh.pk.data, sizeof(sh.pk) );

下面是一个将十六进制字符串转换成字符数组的函数,来自于fc工具中,加上去即可。

 size_t from_hex( const std::string& hex_str, char* out_data, size_t out_data_len ) {
std::string::const_iterator i = hex_str.begin();
uint8_t* out_pos = (uint8_t*)out_data;
uint8_t* out_end = out_pos + out_data_len;
while( i != hex_str.end() && out_end != out_pos ) {
*out_pos = from_hex( *i ) << ;
++i;
if( i != hex_str.end() ) {
*out_pos |= from_hex( *i );
++i;
}
++out_pos;
}
return out_pos - (uint8_t*)out_data;
} uint8_t from_hex( char c ) {
if( c >= '' && c <= '' )
return c - '';
if( c >= 'a' && c <= 'f' )
return c - 'a' + ;
if( c >= 'A' && c <= 'F' )
return c - 'A' + ; eosio_assert( false, " invalid char \n");
return ;
}

到此为即,我们实现了数据的签名验证,也可以将此功能加在其它项目中以增加数据的安全性。

												

EOS 数据签名与公匙验证代码用例的更多相关文章

  1. 针对远程Git代码库使用SSH公匙

    → 运行Git Bash→ 创建SSH公匙和私匙ssh-keygen -t rsa→ 输入SSH公匙存放文件,选择使用默认的,按Enter→ 如果已经存在,提示是否重写,输入n,按Enter→ 打开C ...

  2. 表单验证代码实例:jquery.validate.js表单验证插件

    jquery.validate.js是JQuery旗下的一个验证插件,借助JQuery的优势,我们可以迅速验证一些常见的输入,并且可以自己扩充自己的验证方法.使用前请先下载必要的JQuery插件:jq ...

  3. SpringMVC学习系列-后记 结合SpringMVC和Hibernate-validator,根据后台验证规则自动生成前台的js验证代码

    在SpringMVC学习系列(6) 之 数据验证中我们已经学习了如何结合Hibernate-validator进行后台的数据合法性验证,但是通常来说后台验证只是第二道保险,为了更好的用户体验会现在前端 ...

  4. php用户验证代码的简单例子

    发布:sunday01   来源:net     [大 中 小] 分享一个简单的php用户验证代码,适合初学的朋友参考,主要学习$_post传递数据及isset检测变量的方法. php简单用户验证代码 ...

  5. react native-调用react-native-fs插件时,如果数据的接口是需要验证信息的,在android上运行报错

    调用react-native-fs插件时,如果数据的接口是需要验证信息的,在android上运行报错,而在iOS上运行没问题.原因是因为接口是有验证信息的,而调用这个插件时没有传入,在iOS上会自动加 ...

  6. Hadoop基础-HDFS数据清理过程之校验过程代码分析

    Hadoop基础-HDFS数据清理过程之校验过程代码分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想称为一名高级大数据开发工程师,不但需要了解hadoop内部的运行机制,还需 ...

  7. 解决视图状态消息验证代码 (MAC) 错误

    https://blog.csdn.net/bingtingabc/article/details/49148745 2015年10月15日 10:05:56 bingtingabc 阅读数:3397 ...

  8. SSH 原理和公匙私匙

    先主要介绍了Telnet.SSH 的通信原理,分析了其通信时的工作流程. Telnet 无论Telnet协议连接的是什么类型终端,都会转换为NVT(Net Virtual Terminal)格式进行通 ...

  9. Shiro权限验证代码记录,正确找到shiro框架在什么地方做了权限识别

    权限验证方式的验证代码: org.apache.shiro.web.servlet.AdviceFilter这个类是所有shiro框架提供的默认权限验证实例类的父类 验证代码: public void ...

随机推荐

  1. 【leetcode刷题笔记】Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  2. bzoj 4034: 树上操作 线段树

    题目: 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  3. django models class 不识别问题解决方案

    目录 1. 事情起因 2. 排查经过 3. 总结 1. 事情起因 今天在写代码的时候,在django 的models目录中新增了一个pkg.py文件,里面定义了一个class, 在执行 makemig ...

  4. ssh免密码登录配置方法,(图示加命令)

    首先,说明一下我们要做的是,serverA 服务器的 usera 用户免密码登录 serverB 服务器的 userb用户. 我们先使用usera 登录 serverA 服务器 [root@serve ...

  5. Fortify代码扫描解决方案

    Fortify扫描漏洞解决方案: Log Forging漏洞: 1.数据从一个不可信赖的数据源进入应用程序. 在这种情况下,数据经由getParameter()到后台. 2. 数据写入到应用程序或系统 ...

  6. canvas线条笔帽及连接

    1) 线条笔帽篇: 1 function draw (id) { 2 var canvas = document.getElementById(id); 3 context = canvas.getC ...

  7. Asp.net mvc 网站之速度优化 -- 页面缓存

    网站速度优化的一般方法 由于网站最重要的用户体验就是速度,特别是对于电子商务网站而言. 一般网站速度优化会涉及到几个方面: 1. 数据库优化 — 查询字段简历索引,使用数据库连接池和持久化,现在还有种 ...

  8. CentOS配置LDAP服务器

    环境:centos 5.8 安装: 1.yum安装oepnldap.openldap-servers.openldap-clients.openldap-devel [root@hao-linux ~ ...

  9. maven可用镜像

    <mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> & ...

  10. 使用pygame制作一个简单的游戏

    翻译自Will McGugan的<Beginning Game Development with Python and Pygame –From Novice to Professional&g ...