Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
362 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。  j3 n: y7 W' J. g. y# }6 r+ o1 s
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。6 ]6 Y3 \4 P; V+ ^
Hash 算法
' y# c5 A7 d( s: ^5 ]( X5 a( qHash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。, r0 ]5 S7 O; d/ W

4 P4 K7 o5 }, r- u注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。: X6 S* f; {/ d# u+ e
哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。" T0 F* }, D: ]  u: x
一个优秀的 hash 算法,将能实现:$ o2 e4 }, k: R9 F: [1 g
正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。
: h/ M  ?: ~) g
7 S$ ^# z8 _5 X& b2 s
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。7 h0 {4 n3 d5 \4 E! E
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
( N$ ~, i% [5 F也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。3 z, u& V: u6 Q# g
Neo中的hash算法; I) v0 g1 Z$ {
scrypt( ^7 z8 T# z- Q8 I1 K
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。1 t! m- K0 W* F; f9 }+ Z0 j
scrypt的参数
% y7 n) n- B3 S% t, [$ Q! T2 xhttps://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors! B, w8 m6 P+ P7 }& s4 |
Cpercival mentioned in his slides from 2009 something around
1 {5 }! u' M+ ?- \' r(N = 2^14, r = 8, p = 1) for
# p& l$ K( _$ lscrypt特点* n; S1 n5 k& O  a( p
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
8 I% b0 w8 g( j: `2 w( L; c+ M( XNeo中如何使用scrypt
. Z' `) K: ?, t+ I// in NEP6Account8 a  j) P$ x/ s! G: ~0 g* ~) a
   public NEP6Account(NEP6Wallet wallet,
* {: n) d7 s2 c& f              UInt160 scriptHash, KeyPair key, string password)0 z3 y5 Z5 a! i6 u4 m3 `
            : this(wallet, " M) z8 A- k" ~  Y
              scriptHash, 7 n6 n) {9 Q! [/ D
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
# S1 m5 X$ V4 j2 b5 t        {
# X2 {& y: \3 `0 K            this.key = key;
# @+ K1 B7 X1 m  R  R        }. t: y, q5 B, u8 p- l. ~& O
// in class KeyPair* ]4 R/ Y& b, J. Z  q( b
public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
" |5 x2 z2 P7 n/ y8 W8 S3 u, E0 K5 ~4 E{
9 {# S/ W! L! y% L7 G    using (Decrypt())- f! Q7 S/ q; L4 v% |8 A" w
    {7 p4 ?2 U( V9 g: n
        UInt160 script_hash = Contract.
1 K  J$ U; {0 B! s$ l4 j4 j            CreateSignatureRedeemScript(PublicKey).ToScriptHash();; T+ o3 O0 J& h, Y
        
7 k" u0 Y0 m. r! H8 V9 @; a- V% Z        string address = Wallet.ToAddress(script_hash);  o2 X" R2 d/ y( l
        byte[] addresshash = Encoding.ASCII.GetBytes(address)
! n9 i$ _' t# q, X- S8 J            .Sha256().Sha256().Take(4).ToArray();7 ^  ~7 g5 i* ]) v  h. T& ~: |
        
2 ?1 s: {$ G7 N, q1 S/ ?( T' K* H; k        byte[] derivedkey = SCrypt.DeriveKey(
) k  r. h9 H. U. G1 w" I            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);5 _' g" J- b1 s
        : f/ k" ^$ G' H( W  L
        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();, ?( ~7 Q% N7 G4 A/ h8 y
        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
, r2 i) f/ l8 b- G3 [        5 c$ b6 d2 J. D
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
$ H0 c& L/ y; y2 V            .AES256Encrypt(derivedhalf2);
4 k/ f/ u4 F3 a        - ~- O. G5 }4 w. j( c+ \7 e5 m7 B% M. g
        byte[] buffer = new byte[39];6 y6 O. ?# d1 N+ ?& R4 v1 J: Z
        buffer[0] = 0x01;& j9 b8 N- Q; q* p& Y$ p" K4 L
        buffer[1] = 0x42;
- ~. F3 t+ D) a: X; B  t; k  P        buffer[2] = 0xe0;, a$ R6 l/ k2 V! y2 h
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
9 k3 M2 x! [1 U/ L6 p+ c' i8 F7 e        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
* A* n, R' {- ^+ b' n, G$ a        return buffer.Base58CheckEncode();
2 h% E. d4 e$ }5 w+ v8 y7 P    }( _$ Z, r  m+ R5 L" k! `# l
}; P4 m' I% `, R2 E; }
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
( W' a7 z: ?0 b3 R* s2 q2 k  ], Q% ~9 rMurmur3. ~% Q" i/ j3 [8 y
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]% g2 P9 Q4 v: c# h, Z! A6 v
Murmur3特点" E4 {3 A0 K4 z* }3 M
1.碰撞率低
" R  v" E3 h$ @) \. q2.计算速度快) q# @4 P3 Z( n7 _  }- K
3.擅长大文件的hash
7 m- O% C* p; B) y  x3 eNeo中如何使用Murmur3% e9 U" X/ S. s! n) U8 c4 D

( i" W5 A) ~7 p) x3 \Neo中Murmur3
; q0 [, t7 e& M+ l, [* CMurmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
% f# W/ E! Z" K- C! E. fRIPEMD-160
# u# @, Z" O9 s6 FNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
8 e, D: E, Z6 p) X! _7 t5 _) L// in neo-compiler/neo/neo/Core/Helper.cs
$ N6 V5 s' R& ~4 T) t$ g0 Q public static UInt160 ToScriptHash(this byte[] script)8 w6 P/ k3 H/ H1 z: r0 f
        {" X0 V" v. U8 Y, q# M# Y% p) F9 U
            return new UInt160(Crypto.Default.Hash160(script));
& ]" W- V4 g. g. ^* u2 C        }1 c# }, b* P) E9 C5 K0 I
RIPEMD-160算法的特点
! K& L# W  M/ C1 A+ ORIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
" v. g/ h" [( ^, [. h( e/ _' Q加密算法体系1 j0 C/ m3 S( R  f  G1 n" v( c
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。! {5 N3 R: |1 w1 x% d+ [  j$ J9 F' k
加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。
  D- a% f0 z5 d7 u# s! ~& m% u解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。
- r% `  w. v' |' e根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
2 `  L  U5 c3 W) f5 ]# n7 D7 ]并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。
2 z& P) K" v8 y7 X: q* p对称加密1 H; q9 S1 t2 o' h: y8 u! f
顾名思义,加解密的密钥是相同的。
2 r, T1 ]& ]3 s2 x7 B! z对称加密优缺点
. q4 E# W$ @& s# ~! a优点是加解密效率高(速度快,空间占用小),加密强度高。2 m: y# c' l4 @3 b( t
缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。% H# V0 o0 a* t( H( p4 P
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
0 J, B3 z' d" |" U对称加密实现" s$ p# s) `1 D8 v/ D# I7 F
对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。* v, t. J) u& P' F5 y) q
代表算法包括 DES、3DES、AES、IDEA 等。0 Y; E0 U6 w' p8 w( o
DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
, r/ L3 C7 w; Z3 ]. Q& y& Q3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
! O2 K1 H" [  K0 ~( x: i7 W  BAES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。6 }8 [! p7 C( g% O% @
注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。. P6 U6 b( K$ M# P1 P7 y6 K
Neo中的AES! E( d1 W% C/ t+ f2 a  f; w7 |
在钱包的加解密中,使用了该算法。, S" ]  P& U6 m7 l7 H
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。  O: `$ ^5 ^* G' R3 v  k

* Y4 N$ ]  P, c8 ^: k0 b拿到私钥
  p9 P1 I# e6 Y7 I2 K具体的过程,后面再仔细研究分享出来。
4 u( K5 a  B- a0 j9 ~非对称加密
& I' e; ?# t) g6 V" H非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。
& o  m3 I, V# t5 O' u. a) o5 K" f9 [非对称加密优缺点, @( y9 y9 S' ~3 `
1.优点是公私钥分开,不安全通道也可使用。8 s2 q; u; ?1 |1 N4 t4 R
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。& X# ?5 {4 g5 ?* {& \/ Z; b
非对称加密代表算法
! M: i, U6 \& W4 `$ x非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。: m0 |% w: |' `8 X- `  Z) e5 |
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
  z( ]/ t1 y5 V. n1 {" A& M' X1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。7 w1 I8 D9 u7 \2 R
2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。
5 g1 {: M; T' C& o% w% i; t3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
* N; V8 x; M! M3 h! E/ }+ k4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。, C  q) y# Q2 t1 U8 I. ?
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。) T5 e1 D! h/ q* i- _* p
Neo中的数字签名算法
' ^( z2 |9 W5 o在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。( t% T  M1 f  ]7 X$ T
public virtual WalletAccount Import(X509Certificate2 cert)
" z, x6 O" C8 k1 O        {
3 l# `# Z" R/ v9 |5 }2 s            byte[] privateKey;
5 Z+ y/ O( i1 }0 W; x            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())* P; |! d7 |) B- G
            {
+ y( R! c$ ]8 I1 e8 k' Q8 N7 U                privateKey = ecdsa.ExportParameters(true).D;
+ F$ m  Y" {& n  @2 o) V! r            }: \" V& [2 G$ \# y
            WalletAccount account = CreateAccount(privateKey);
  ^$ s# ?7 @* k- d/ f( Z5 j            Array.Clear(privateKey, 0, privateKey.Length);
# }0 J3 ]) A) u            return account;8 Q0 f, B/ }7 n& D# K
        }
4 M% S+ U1 r' j0 Z8 MX509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
4 Q; W* N3 y" R1 ?' a总结6 x1 z5 z7 g3 j% @1 R% ^8 k
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
" T' p0 U- w/ O1 H2 e5 D& O. E" ]* W参考资料
* J% j+ p8 I+ _  p' t区块链技术指南
7 Q/ c! S2 s, V- ^MurMurHash3, an ultra fast hash algorithm for C# / .NET
1 L" c& S) ]8 X  \  Z2 }scrypt算法的前世今生(从零开始学区块链 192)
$ t8 k) v0 c" m; ^' |6 k: wWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3