Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
369 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。
/ ]4 G* q$ a' A3 r9 b; m关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。0 C2 v7 A# R; B, z
Hash 算法
" p3 \- {: `/ E& e# B4 F8 C' mHash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。# j" `; ^3 }- U6 }% @
( T; K0 _0 p' p1 p( t: T
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
7 |! [) }5 i) }, ~9 }2 N哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
5 G7 k& V3 z& W% S6 g5 K+ m6 r. F! Q一个优秀的 hash 算法,将能实现:
' J/ w* Z1 ?# ~  q1 J- U: o正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。
* T* J2 K$ S! K

1 d) e$ U% K# Q" ^& \目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
! g3 G6 v3 ~$ X% B一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
) G2 ^4 n0 n& x6 ?/ j0 K& B; n也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。& H+ \, [* X; H- e9 ^0 N/ M/ ]
Neo中的hash算法/ s2 g7 }2 J5 p& r" v% s
scrypt$ S; ?, ^$ r2 L2 @% Q: r7 g4 Q0 j
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。9 Z/ {8 y# s6 o4 v
scrypt的参数
4 A" a6 ^7 ]& a* p- q# P/ p$ |, ahttps://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors1 r( U6 B9 b# ?
Cpercival mentioned in his slides from 2009 something around+ f  Q" d: ~& z) s, X
(N = 2^14, r = 8, p = 1) for ' _$ j' b5 G- ?7 c' H9 _, ]
scrypt特点
" E7 Q) D* z" i, v: r7 V7 P3 D( ]scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。' p& L8 E- r/ `* Y1 \, ]3 Z
Neo中如何使用scrypt
7 v, g. Y5 U& K( s+ Z// in NEP6Account" h2 g: z' X* a3 t. u
   public NEP6Account(NEP6Wallet wallet,
; k+ g7 b2 `4 A5 z. A3 q4 v& x              UInt160 scriptHash, KeyPair key, string password)
0 O1 ]5 A, i0 P: ?1 t% I. K            : this(wallet,
' f) |$ F( ^# {. ~( \; z" n& j              scriptHash, 3 f0 L2 i3 t" }( ~
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
' g4 C7 {  }! K6 W* b) d        {
" s, U  W7 x! b# g% n+ {: q            this.key = key;
8 c. u, p0 m( f3 }% h        }
: Q: {$ P" ]; F/ p4 ^// in class KeyPair
  G+ l) P- I9 }public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)( v* G  P* J3 u  y/ l) y/ l
{
: Q: p- g0 Q/ Z* H$ i# R6 H3 L& W/ Z    using (Decrypt())
: J( K* w+ C7 r4 e    {
2 F7 }# e+ Y8 E8 G        UInt160 script_hash = Contract.0 i( h7 @0 O9 y8 d0 Y7 }
            CreateSignatureRedeemScript(PublicKey).ToScriptHash();
2 @  ?/ b0 Z3 a3 p( R( O        2 w: c; Q3 ]" ?- B# L; n% ^, r
        string address = Wallet.ToAddress(script_hash);0 b# t- o3 o9 Y
        byte[] addresshash = Encoding.ASCII.GetBytes(address)% t4 z% I' ?) }2 K
            .Sha256().Sha256().Take(4).ToArray();
" X1 Q; ?6 w! W" Y5 {        , G" e( b9 T+ p' ~* J6 M% |
        byte[] derivedkey = SCrypt.DeriveKey(4 y, t0 M# I& Z5 y7 m+ N" {& S
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
+ G; S: n3 I! v  }3 C! C9 Y" E% ?        
1 q' G& n0 ?9 H6 F        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
: N5 x; L" j# t- I& F/ q        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
6 w3 l% ^- O+ `1 ]        ' h0 r; w: \5 m  u+ S+ d
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)/ M; @( N" \  m! |$ n+ K. A
            .AES256Encrypt(derivedhalf2);9 @& P# L! i  E  B8 Z
        
4 ]5 n5 j4 C% a( w        byte[] buffer = new byte[39];
3 i/ y; i: ^9 w: ^6 C        buffer[0] = 0x01;
9 d4 ~8 _- K' h" w        buffer[1] = 0x42;5 {3 T9 Y4 G" F5 V$ M- V5 O
        buffer[2] = 0xe0;" |# U0 m5 s. I; a: b0 E% X
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
7 ^9 U" J/ _$ t% h$ n1 I  R( U        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);! }  s& c" z9 [6 A. I4 j
        return buffer.Base58CheckEncode();
/ J. }: Z- t, ]' C' c$ Z2 P8 D    }
' U! a: d! {! {5 P}2 s( _1 h$ N1 Q8 j  r2 Z
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。3 k# {+ L0 j/ S0 s0 `+ n/ [4 |0 X
Murmur3, U# b$ o' @( k6 y) J( {
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]4 k0 v/ I% E; ]4 G
Murmur3特点
* r. ]) b5 ^6 v- g/ r; z. ?1.碰撞率低- `) i7 g2 t$ X  H0 M3 d! d8 r% i
2.计算速度快6 E1 E# V" V) f) P
3.擅长大文件的hash* Y: d# Q5 Q% _( K
Neo中如何使用Murmur3
7 i) g6 C  \; R9 X* Z- Y: Z. {6 l
$ x* @7 U7 S& ]: h* {7 \+ g' KNeo中Murmur3
$ U' h$ G, G: LMurmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
2 ?) w' ^. W0 Y9 {6 d  w# vRIPEMD-160, U# i- ]7 k5 S( I( D
Neo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
4 s4 i$ b  d% O( X// in neo-compiler/neo/neo/Core/Helper.cs
! }- p8 o; T* F( ]3 y# x public static UInt160 ToScriptHash(this byte[] script)& ]% t6 l5 H- a: r  E
        {
4 M& a2 J. D0 ^9 {% f$ y5 Z+ G2 s" D3 t            return new UInt160(Crypto.Default.Hash160(script));
; F; w' v( C: S0 S) T9 G2 q$ f0 h7 F        }" _$ A. h2 y6 n* Q( T6 F
RIPEMD-160算法的特点" N/ ?( O. S+ h5 i5 G1 n
RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):8 J6 ^) U, M7 r1 k3 |6 [
加密算法体系
  A& i5 U0 j; W$ f9 y) y! D现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
4 ^  v+ o7 P& V) r加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。3 w0 `' h+ ~+ ^: R9 h
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。
1 @- X2 _6 W' T1 B8 y  Z) N% O根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
* Y& l$ b9 L& L6 k! n5 a) F" W/ ^+ L并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。
' W* t9 N" d; D9 e. u8 o对称加密% ^! R  m, Y5 B* ~1 E4 ?* ^; Q# A
顾名思义,加解密的密钥是相同的。6 m0 \$ F# s0 `5 C
对称加密优缺点) D3 p. w/ a" @" G' P0 d( r, v
优点是加解密效率高(速度快,空间占用小),加密强度高。
! g: Y7 l% E1 _3 j, `' v$ a# p3 x9 P缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。" I- u$ c8 l: N( Z6 a
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。/ [$ c- U8 J6 G7 o, s( e- W
对称加密实现+ r$ C0 k' g( @" C1 N/ d3 ~
对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
  z( h/ H% y/ \$ E( L9 h代表算法包括 DES、3DES、AES、IDEA 等。
* {+ X: }8 T3 ]( c2 `+ T: x$ iDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。  G3 e/ T# ~+ Q+ I6 P
3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
8 j' v: V) v$ G! e% Y! t4 fAES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。( v5 d1 I) `; Z) E
注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
9 T4 Z" |3 S9 nNeo中的AES5 _$ ^4 y1 D2 v% |5 z' h; [
在钱包的加解密中,使用了该算法。
  ?# B( b& I$ `3 K9 `" I下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
+ O0 M* B. \" a9 ~. t
6 K/ q  @0 C% ]% g! O拿到私钥5 L1 Q3 b/ b1 b
具体的过程,后面再仔细研究分享出来。+ |, i4 p6 o8 W! `: r" S, L+ N
非对称加密$ y5 G' D. y* v5 C
非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。
# g7 Y. H# v" o8 U  C4 p非对称加密优缺点
1 G) @; y* R# q" x1.优点是公私钥分开,不安全通道也可使用。3 M% M% _) |0 ~3 P. K; w) f$ N
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。/ x, N8 v" J" h; {3 U; q
非对称加密代表算法
. e6 s( k; n  {* {非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。- A9 Z; J' l. j$ ]9 L
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
* r5 _! G" G4 A, a  I1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。9 v+ Q0 L1 V+ z& T" U
2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。* G# i' m2 p& Y3 _3 U/ J
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
) q5 h6 E- E. O3 M8 B4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。& }5 B% k  v0 @/ L( [, U1 C
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。$ [! a; P( b; m4 R  \9 e: ^  X
Neo中的数字签名算法
) O$ _, K* \. W# J5 X在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。% I: S8 m3 X" O* ?% M
public virtual WalletAccount Import(X509Certificate2 cert)$ |& R* H$ L! G; A2 q+ d
        {
$ s$ C4 x% C3 _0 N/ O            byte[] privateKey;
8 X0 T3 w- E# Y2 L  c1 Y            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
" \8 L5 o; Z  `/ y4 W6 F$ p8 \3 s, I            {
: q( i  z) t( k- ~. l# k1 x" c                privateKey = ecdsa.ExportParameters(true).D;
3 _# Z' g2 w7 {8 p/ z$ J* ?            }
2 n  I6 Y- L5 ^2 t/ T" m- g            WalletAccount account = CreateAccount(privateKey);5 u1 Z1 j5 u1 C+ W
            Array.Clear(privateKey, 0, privateKey.Length);3 ?0 @" @2 @' _2 \# J9 a
            return account;
9 w3 ^/ g- K4 j- K6 I" y        }' p8 f  s, J( Y  H# ]
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。8 ~, u' f3 b  ~& h1 B9 O1 h  k) g# h
总结) B; z/ }. J0 Y* H, v8 m
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。9 ?& q: b8 O3 G5 D
参考资料4 h2 j) g$ z5 k: a; }! y
区块链技术指南
7 q0 ^/ {5 t, G, }MurMurHash3, an ultra fast hash algorithm for C# / .NET
* d+ H# v' A3 c3 r1 |# Fscrypt算法的前世今生(从零开始学区块链 192)
/ D! p6 u. J/ K% y$ OWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3