Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

Neo中hash算法,加密算法使用介绍

空港训港j
446 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。
, `! D+ o  T% d/ m, _/ w# ~, f/ a关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。$ z8 M+ G6 p0 w. L& s$ R
Hash 算法
' d7 V7 D1 Y2 w. r- x- e$ O1 KHash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。& F: u+ `( _3 p, x. e: [
7 k* {( \' \: \2 _& l" U
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。& T/ M5 _, Z6 E0 _2 `5 Y9 `" m
哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
# ~( {) ]& ^" V" |一个优秀的 hash 算法,将能实现:, K  I# a- [* Z. B$ }/ ^
正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。
7 q# d' \' T$ V* r
2 N" T5 n- _2 c
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
* ~) H6 d: O3 Z: h一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。% C( ]% Q5 |/ d* Q( _! S  P; @
也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。
. L' [7 \7 e. ]& c" V* `- uNeo中的hash算法" d' p9 Z6 J0 W+ ~- B- V
scrypt
  j/ o/ A6 ]* N" ?  f" hscrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。( P4 o. ]2 S) l2 J7 ?) j# ^8 ]9 o
scrypt的参数
6 y; q) b+ Q7 m  L$ @, x8 Vhttps://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors9 U0 ?! x0 i: O7 h& K; G# Y
Cpercival mentioned in his slides from 2009 something around
. n$ V' {! p7 _(N = 2^14, r = 8, p = 1) for / B1 h5 a" ~& R3 m' h3 O, _0 F
scrypt特点
& x. Y" ^+ Y& H1 c/ _/ O$ escrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。( t/ Z( B' j! C: [
Neo中如何使用scrypt& |9 H/ z$ C: U  d) M/ A
// in NEP6Account
+ T0 |* `* v, N) F' J! _   public NEP6Account(NEP6Wallet wallet, $ k8 F' ~0 m% R$ y
              UInt160 scriptHash, KeyPair key, string password)+ A5 y, E2 U7 ~" x$ C
            : this(wallet,
3 G# S# i& Y) _- N# z3 U: i              scriptHash,
+ H% ]5 f4 e2 G9 g              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
/ V; i3 s) }3 O+ Z" _7 L7 C% z# N        {% W' h( |$ l1 Q8 n) y9 `2 e2 G+ W7 Y
            this.key = key;2 S% T5 ~- h! t* q7 F
        }
; U. r. U$ q  j+ s// in class KeyPair! |  V( `9 u9 @& R8 V4 n7 r5 _" B
public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
$ q0 G) p" Z- g% w/ Y1 l{
- ^7 Q" _+ b; P" M    using (Decrypt())
. P) I5 L7 o- p: w, Q( I- j; R    {
  m. ~; B) c/ t! e1 a        UInt160 script_hash = Contract.0 m/ B5 L8 B4 T/ f! b
            CreateSignatureRedeemScript(PublicKey).ToScriptHash();2 q$ f* y; o( R/ }3 V* d1 V0 T$ q  K
        , Z' E. q5 h* R% R- M0 c, O
        string address = Wallet.ToAddress(script_hash);
: _* j% f, O% y6 M4 N# S9 N        byte[] addresshash = Encoding.ASCII.GetBytes(address)( I$ c  m2 W; i
            .Sha256().Sha256().Take(4).ToArray();) N" `# t" o. y( ~6 L- k
        6 S/ _6 O- s& q) c+ Y, v6 E) Z
        byte[] derivedkey = SCrypt.DeriveKey(, m  N) Z, _* [( E  y% {4 w
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);- [" Y: p" o. t( a9 N+ E& G
        
% t- \0 R* D" }8 l" C3 y* a) A# X* f: L        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
& s! G6 I/ s' u        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();$ O. {- R. e& Q/ R8 Y& T
        
) ~) W; `  h4 Z/ [6 {        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
6 @: V6 \2 E9 i$ Y& g            .AES256Encrypt(derivedhalf2);# ?! j" w5 C/ v: {9 C
        & i0 B. k9 F" _% W  Z7 V/ Z
        byte[] buffer = new byte[39];( T3 r4 |+ G& y7 ]5 t$ A
        buffer[0] = 0x01;  V3 L1 |8 n. W+ l/ Y4 M
        buffer[1] = 0x42;% p2 z1 g( E) Y
        buffer[2] = 0xe0;
! e4 U9 ]9 |7 k# R4 l+ Y        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
' {( N+ C( _( R7 M0 k        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);6 h$ ?+ K$ [. x' q; E/ Z8 J
        return buffer.Base58CheckEncode();
: \$ z0 C4 ~: p8 \8 E    }
4 \% o2 M0 q9 r! ^}8 N1 A  X) {$ {5 l
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
' a, q/ o9 P* b+ g( xMurmur3
& w/ n2 P/ V. M1 J: Q1 G7 w6 I. pMurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]/ e; ]: R* g. `) c" w
Murmur3特点/ u' X. M' o4 M. ?* m  x
1.碰撞率低
& O  z$ g: Q, P3 V( a2.计算速度快  G/ j6 G6 x8 L" c0 E/ u
3.擅长大文件的hash
6 J6 L1 [& h, n$ UNeo中如何使用Murmur3- N, k, _" A& x7 o! d, A. o5 k2 n
) s3 |( D; I, L! u$ Q0 d
Neo中Murmur39 T+ k+ u) t& v( W8 F& q
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
& _2 R( }  N4 {( z, o: `RIPEMD-160
7 Y# l( Y4 H5 U2 j: bNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
7 B; J* Z/ r& I$ }// in neo-compiler/neo/neo/Core/Helper.cs3 ?. H) ]4 W- |' Z# l1 P. c0 h
public static UInt160 ToScriptHash(this byte[] script)" n, k( I  |% @5 P7 \8 d- P, p: q
        {
  ^% P1 u7 y' [+ Q            return new UInt160(Crypto.Default.Hash160(script));
# s8 J6 i- S5 X. F* {        }% P# H& H- d# c  M( h
RIPEMD-160算法的特点
4 v9 c# y- u& NRIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
; \8 T' }6 O( _, l加密算法体系. N% k) n! Z- }! V' I, E
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
. U+ I8 T( R4 T# Z5 @" @加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。8 S# T% C( c3 {# o( k
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。7 v' B6 i6 c/ s
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
( l# D- E, ?5 b( |1 w并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。# b) b" Q5 n' i' a+ u$ l1 j: d1 k, m
对称加密# w& t) @6 F% ~; N
顾名思义,加解密的密钥是相同的。
6 l2 Q. q( l$ @9 w对称加密优缺点5 X8 Q; `0 R6 m/ T+ ^
优点是加解密效率高(速度快,空间占用小),加密强度高。6 J8 G8 t+ f5 _
缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。7 O6 A) _# v7 z) N$ a
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
  I; ?: n6 n, k2 \  D1 j, Q* U对称加密实现$ u0 `! k( L5 j9 C& S
对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
# x& \$ t8 Z; f, z" Q代表算法包括 DES、3DES、AES、IDEA 等。
' {# @& `" \. Q% s; d2 \DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
1 D) r0 O, H# c& S! e" m3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
0 u2 ~1 @/ ?' A: j1 sAES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。' \9 `. ^8 k2 x+ J# x9 m- O! G
注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
$ H" k% c1 J$ X9 h2 \% p6 |Neo中的AES
- w+ \, r+ n1 u0 |) V$ p在钱包的加解密中,使用了该算法。
# g* s" A0 E; G1 v3 M: \' s: X6 d0 s下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
0 s6 G# |) D2 f0 U, z" `
' u& {9 R, [2 T6 U  [* U5 L: o拿到私钥- o' Y  n6 ?; d4 r# Y
具体的过程,后面再仔细研究分享出来。5 I3 m0 @3 s" F4 C: U8 b* k( u4 ~
非对称加密8 ]- E. a8 J2 z+ \& G, m: r
非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。9 y8 d8 ?$ _/ \4 {0 l$ l1 k. W+ B
非对称加密优缺点
" V& i( T0 @. i4 ^, j; O5 G1.优点是公私钥分开,不安全通道也可使用。7 L; y% Q9 F: {/ K
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。
1 h9 Z( ]6 \+ O0 N; h1 t非对称加密代表算法
) ^0 i$ k% a4 J+ o7 ~非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
8 Z$ d# w9 P6 _# o' \- i/ g代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
1 _  C/ [1 t% l& t1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。  ?: A1 Z8 V% T/ E+ N
2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。
+ z8 U5 T* a: r' T  w2 B3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
+ P5 Q: s" U6 l* ?# a; P4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。! |4 B4 p% P9 F( Q4 C
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
9 Z% r. i& i% MNeo中的数字签名算法! F" R# Y* z  O* f7 s; M
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。7 o6 P0 z( O2 v; I
public virtual WalletAccount Import(X509Certificate2 cert)) A8 c, |: }) Q0 j* w4 b
        {
% R$ v9 {' s) N, J            byte[] privateKey;. f- D$ K; X7 Z. X. a1 G- L
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
) _6 x: B" Z, K7 H( t$ B            {6 x! d$ ~5 [! A  y% ]! _
                privateKey = ecdsa.ExportParameters(true).D;
& D% {3 d2 b8 E            }
- `! \0 e. i7 C0 j$ `, C, Z% p% Y7 D            WalletAccount account = CreateAccount(privateKey);" }9 w* j' p- D, V: _$ _
            Array.Clear(privateKey, 0, privateKey.Length);
0 T5 m) y. }, H4 ]! A            return account;( s2 o4 ^4 H5 Y% C' X
        }
5 H* @# Z+ [- H$ B+ bX509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
& q3 \$ r5 M6 Z0 Y1 D/ j- [( p4 V总结" Y' _6 Q3 y- v2 B
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。8 F+ t9 ^9 g0 {. k) K
参考资料
; C2 S% w, x  q区块链技术指南9 Y( b  W; I& V8 [
MurMurHash3, an ultra fast hash algorithm for C# / .NET
9 m! d! M+ s: k* \2 [& ?! ]! {, Nscrypt算法的前世今生(从零开始学区块链 192)
  B; e# X2 M# i- [1 m( O8 GWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3