本文编写了一个小例子诠释了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. CSS cursor 属性--css html 鼠标手型,鼠标形状,鼠标效果,样式

    css鼠标手型cursor中hand与pointer Example:CSS鼠标手型效果 <a href="#" style="cursor:hand"& ...

  2. 关于CString与VARIANT(CComVariant)之间的转化

    一.VARIANT.CComVariant类与CString是什么: CString是MFC定义的字符串类,VARIANT是COM标准为了使COM组件能够被各种语言使用(vc++.vb.java.py ...

  3. 数据交换格式XML和JSON对比

    1.简介: XML:extensible markup language,一种类似于HTML的语言,他没有预先定义的标签,使用DTD(document type definition)文档类型定义来组 ...

  4. informix 把数据从一个表倒到另外一个表中

    drop table zrjReinUnClaimTmpT; create table zrjReinUnClaimTmpT ( mainid SERIAL not null, RepayNo var ...

  5. 流媒体直播服务器:Bull-Live-Server

    Bull Live Server 简称 BLS ,旨在使用C++语言提供强大功能和高性能的流媒体直播服务器. 为何要写 BLS ? 1.simple rtmp server https://githu ...

  6. 强烈建议使用国外DNS解析域名,解决访问速度和某些访问故障!

    域名解析的基本原理是把域名翻译成IP地址,以便计算机能够进一步通信,传递网址和内容等. 域名劫持就是在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则直接返回假的IP ...

  7. Windows 7下Git SSH 创建Key的步骤

    1.首先你要安装Git工具 下载地址:https://git-scm.com/downloads 2.右键鼠标,选中 “Git Bash here”,当然你也可以在windows的 “开始”---&g ...

  8. LAMP 1.2 Apache编译安装问题解决

    这个错误安装 yum install -y gcc error: mod_deflate has been requested but can not be built due to prerequi ...

  9. shell入门-变量

    shell变量分为系统变量和用户自定义变量 查看变量的命令 #env        系统变量 或者 #set    包括env和自定义变量和额外变量 使用变量的命令是 #echo $[变量] //// ...

  10. 利用Ssocks访问国外网站(yutube/google等)

    ***开源项目:https://github.com/***/ 本例使用的是针对windows系统的c-sharp版本:https://github.com/***/***-windows 运行*** ...