作者:沈寅

原文链接:https://www.jianshu.com/p/3fef5d95bf9f

区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。

Hash 算法

Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。

hash函数的作用

注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。

哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。

一个优秀的 hash 算法,将能实现:

  • 正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。
  • 逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。
  • 输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。
  • 冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。

目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。

一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。

也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。

Neo中的hash算法

scrypt

scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。

scrypt的参数

https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors

Cpercival mentioned in his slides from 2009 something around

  • (N = 2^14, r = 8, p = 1) for < 100ms (interactive use), and
  • (N = 2^20, r = 8, p = 1) for < 5s (sensitive storage).

Also, those values (mostly) mean:
N: General work factor, iteration count.
r: blocksize in use for underlying hash; fine-tunes the relative memory-cost.
p: parallelization factor; fine-tunes the relative cpu-cost.

scrypt特点

scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。

Neo中如何使用scrypt

// in NEP6Accountpublic NEP6Account(NEP6Wallet wallet, UInt160 scriptHash, KeyPair key, string password): this(wallet, scriptHash, key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P)){this.key = key;}// in class KeyPair
public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
{using (Decrypt()){UInt160 script_hash = Contract.CreateSignatureRedeemScript(PublicKey).ToScriptHash();string address = Wallet.ToAddress(script_hash);byte[] addresshash = Encoding.ASCII.GetBytes(address).Sha256().Sha256().Take(4).ToArray();byte[] derivedkey = SCrypt.DeriveKey(Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);byte[] derivedhalf1 = derivedkey.Take(32).ToArray();byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();byte[] encryptedkey = XOR(PrivateKey, derivedhalf1).AES256Encrypt(derivedhalf2);byte[] buffer = new byte[39];buffer[0] = 0x01;buffer[1] = 0x42;buffer[2] = 0xe0;Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);return buffer.Base58CheckEncode();}
}

可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。

Murmur3

MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]

Murmur3特点

1.碰撞率低
2.计算速度快
3.擅长大文件的hash

Neo中如何使用Murmur3

Neo中Murmur3

Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。

RIPEMD-160

Neo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。

// in neo-compiler/neo/neo/Core/Helper.cspublic static UInt160 ToScriptHash(this byte[] script){return new UInt160(Crypto.Default.Hash160(script));}

RIPEMD-160算法的特点

RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):


加密算法体系

现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。

加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。

根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。

并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。

对称加密

顾名思义,加解密的密钥是相同的。

对称加密优缺点

  1. 优点是加解密效率高(速度快,空间占用小),加密强度高。
  2. 缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。
  3. 适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。

对称加密实现

对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
代表算法包括 DES、3DES、AES、IDEA 等。

  1. DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
  2. 3DES:三重 DES 操作:加密 --> 解密 --> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
  3. AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。

注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。

Neo中的AES

在钱包的加解密中,使用了该算法。
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。

拿到私钥

具体的过程,后面再仔细研究分享出来。

非对称加密

非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。

非对称加密优缺点

  1. 优点是公私钥分开,不安全通道也可使用。
  2. 缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。

非对称加密代表算法

非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。

  1. RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
  2. Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。
  3. ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
  4. 椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。

RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。

Neo中的数字签名算法

在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。

public virtual WalletAccount Import(X509Certificate2 cert){byte[] privateKey;using (ECDsa ecdsa = cert.GetECDsaPrivateKey()){privateKey = ecdsa.ExportParameters(true).D;}WalletAccount account = CreateAccount(privateKey);Array.Clear(privateKey, 0, privateKey.Length);return account;}

X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。

总结

目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。

参考资料

区块链技术指南
MurMurHash3, an ultra fast hash algorithm for C# / .NET
scrypt算法的前世今生(从零开始学区块链 192)
Wallet import format

Neo中hash算法,加密算法使用介绍相关推荐

  1. hash算法_阿里面试官:讲一下Hashmap中hash算法!

    注:本文内容全部基于jdk8讲述. 相信很多人都知道,在JDK8中,HashMap的容量总是2的n次幂,那么这么设计的目的究竟是什么呢?我可不可以将默认的初始容量从16改成20呢,扩容的时候我可不可以 ...

  2. [区块链] 密码学中Hash算法(基础)

    在介绍Hash算法之前,先给大家来个数据结构中对hash表(散列表)的简单解释,然后我再逐步深入,讲解一下hash算法. 一.Hash原理--基础篇 1.1 概念 哈希表就是一种以 键-值(key-i ...

  3. Python中hash算法

    文章目录 简介 概念 特点 hash有哪些 算法碰撞 加盐防碰撞 加密 hashlib 主要方法 特有方法 使用方法 加盐 crypt 主要方法 使用说明 应用 密码加密 应用一致性校验 简介 概念 ...

  4. Redis数据库中Hash哈希的介绍,常用命令和应用场景

    一.简介 Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. 可以看成一个map容器 Redis 中每个 hash 可以存储 232 - 1 ...

  5. 浅谈网络爬虫中广度优先算法和代码实现

    前几天给大家分享了网络爬虫中深度优先算法的介绍及其代码实现过程,没来得及上车的小伙伴们可以戳这篇文章--浅谈网络爬虫中深度优先算法和简单代码实现.今天小编给大家分享网络爬虫中广度优先算法的介绍及其代码 ...

  6. HASH算法不是加密算法

    HASH算法不是加密算法 作者:itwriter出处:博客2011-12-26 07:48 在 CSDN 密码泄漏事件中,网友评论提到密码的明文保存和 MD5 保存问题.目前,很多站点都用 MD5 算 ...

  7. MD5算法原理简要介绍并采用C#应用在桌面应用系统的用户登录与注册中

    MD5算法原理简要介绍并采用C#应用在桌面应用系统的用户登录与注册中 接上文,本文简要介绍一下MD5加密算法的原理,并采用C#实现MD5算法的加密与解密过程,将这一实现过程应用在我自己开发的桌面办公应 ...

  8. 分布式系统:一致性hash算法 在分布式系统中的应用

    前段时间在了解分布式,发现firefoxbug在博客中写的这篇<一致性hash在分布式系统中的应用>对这个问题说明得比较清晰易懂,本文主要是自己的理解和实践. 在后端一般会遇到这样的场景: ...

  9. DPDK中的cuckoo hash算法

    现在用到的cuckoo hash算法比较多,下面具体分析在dpdk代码中cuckoo实现,在lib/librte_hash/下有其他若干种hash就不一一介绍了,比较简单,先文字介绍下bloom fi ...

最新文章

  1. 25个让人惊叹的 HTML5 应用实验
  2. python基础4(来自廖雪峰的官方网站)
  3. 12c集群日志位置_面试问Redis集群,被虐的不行了......
  4. 20200314 SQ Intel Realsense D435 USB 线长、转接线个数测试数据表
  5. 泛型(java菜鸟的课堂笔记)
  6. C语言实现Winsocket网络传输数据时乱码问题
  7. 大数据之-Hadoop之HDFS_HDFS产生背景以及定义---大数据之hadoop工作笔记0048
  8. 【Maven】import maven依赖安装失败——暂时玄学解决
  9. LeetCode Binary Tree Right Side View (DFS/BFS)
  10. cocos2d-x游戏引擎核心(3.x)----事件分发机制之事件从(android,ios,desktop)系统传到cocos2dx的过程浅析...
  11. linux shell脚本 main,Linux shell启动Java Main函数脚本
  12. 百度云下载插件,创建链接,脚本管理,百度网盘快速下载
  13. 腾讯云如何申请免费服务器试用
  14. 【微生物相关数据库】NAR database issue
  15. java 学习7.13 正则表达式 Pattern和Matcher类 Math类 Random类 System类 BigDecimal类 Date类 SimpleDateFormat类 Cale
  16. laragon 之Nginx
  17. Windows 10错误在打开特定路径时导致BSOD崩溃
  18. hbuilderx使用字体图标
  19. Linux qt shell脚本,QT执行shell脚本或者执行linux指令
  20. 输出1到2000之间的双胞胎数。双胞胎数:两质数差为2称为双胞胎数。例如227和229是一对双胞胎数,它们都是素数且差为2。

热门文章

  1. Python错误总结:Python读取文件报错
  2. 空气断路开关的原理、种类及应用
  3. Python爬取LOL高清皮肤壁纸
  4. C++ 如何正确高效地定义字符串常量
  5. POI 导出横版A4word,并设置excel宽度(固定不变形)
  6. 2021年安全员-A证考试及安全员-A证证考试
  7. iOS内购—— In-App Purchase(消耗型)
  8. MySQL命令行下载安装配置——详细教程
  9. sqlsever数据库用户管理
  10. 要是我有这个女孩才华万分之一,那就不用去搬砖了