Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
338 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。
$ k8 M$ h0 h( \7 X6 t" b& U2 W关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。
5 ]3 x  M* w! c3 w; t/ UHash 算法. C; C* G  |; N0 ?: J- m
Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。; Q& Q6 }$ J+ L/ e" x
( H* o: o: ^$ }' N
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。; A- x% B0 G2 {+ y
哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。7 K( j' j1 N3 I, z- A2 ^1 o: m
一个优秀的 hash 算法,将能实现:; F. g/ S0 r4 G# M9 I0 F
正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。$ C! i! q3 I, |. d/ j
" h. D/ o8 g. t/ T* y0 J4 [: l$ J; q
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。+ E. v  Y- c# Q$ n' }7 v
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
% a/ J$ z5 e2 P) ~也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。! \& W+ O* F( f/ ]- G5 b: ]
Neo中的hash算法
6 g7 g! p- y8 G% Q! Yscrypt2 ]# @' q; M4 Q9 Y) h! O
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。( P7 j$ P4 b6 [( P; W$ {1 r& d) B
scrypt的参数
5 T2 C) J. o0 z. C0 Hhttps://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors; B" H8 p6 Q: g- R1 A
Cpercival mentioned in his slides from 2009 something around
: o% v3 f+ X3 ~/ p9 \& S; E' {(N = 2^14, r = 8, p = 1) for ; z( T2 h0 T+ X. }9 h1 m
scrypt特点
: H7 S4 _: U! o, `- Escrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
0 N2 [/ R# e, {- mNeo中如何使用scrypt' Y9 ~: A8 I( S0 E# T( Y+ S
// in NEP6Account
& |* \. U. F3 f1 Q7 V/ F* z   public NEP6Account(NEP6Wallet wallet, # Q& E. Y! z/ l- ^$ F/ V: ]
              UInt160 scriptHash, KeyPair key, string password)
  }% i& c) H( v2 M" F            : this(wallet, 6 \7 e: r6 @* u
              scriptHash, : h- k! _% W) `* d8 }9 j6 L9 B
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
% s( z' E, D& d: G( [6 I/ J        {5 O8 N6 ^: G/ V/ z( q) S$ ?; E
            this.key = key;* b& w0 @* q) a9 p# F1 w9 B8 P
        }9 p+ _3 x* D" N* y2 m
// in class KeyPair  O3 s3 ?8 X8 d% _% |
public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
! z" T3 Y) Y) H{
6 @/ e1 M3 @" K  u- Z6 q9 R    using (Decrypt()): r; K- A: a; P1 r7 h/ _
    {
, x' a, w. O' N0 q* g5 h        UInt160 script_hash = Contract.. u& F5 z: u+ ]/ [
            CreateSignatureRedeemScript(PublicKey).ToScriptHash();' n. _4 t! T9 V: p1 v
        
+ h  J+ E  o% }- A5 X( j* c        string address = Wallet.ToAddress(script_hash);4 A* z9 x* m* G4 V
        byte[] addresshash = Encoding.ASCII.GetBytes(address)
4 D3 G4 P9 \/ m& Y& O; h! h/ G            .Sha256().Sha256().Take(4).ToArray();
1 _1 q+ _  m4 `' n& g        - ~( y3 f' I0 N
        byte[] derivedkey = SCrypt.DeriveKey(7 j  D8 e$ p9 C2 M) Z& S1 O* ^
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);7 m1 w, I) |( J# g# M
          o  [# Y; g5 `+ D* w* t4 @
        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
* \) q1 l1 K9 y$ d0 A0 T        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();7 ]) i6 ]$ `7 d
        " A6 o' G% W* ?3 a
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
; B4 p$ |1 Z7 V: U0 a) J( i            .AES256Encrypt(derivedhalf2);, z% T. b1 ^- z
        
2 Z7 i& u! |( X! h7 ^4 f        byte[] buffer = new byte[39];% t1 L& w3 U* _, j* Q1 O
        buffer[0] = 0x01;
! r0 l3 i- J$ F9 X- K+ k, Z2 M        buffer[1] = 0x42;) p* f4 J! [# D- B$ a8 q2 t
        buffer[2] = 0xe0;: j- M+ P4 X+ r! h& `
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);9 m' m* p- E7 G, @$ |" y
        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);. @' F+ W& j* L" j- I1 {; ]4 ]* V
        return buffer.Base58CheckEncode();
1 J( o' n# u3 j9 m9 p% \! E. N    }  P& U- g/ u" J  e! Z9 m  T. e6 N, z
}! h( A: A# O* A+ p( l
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
! `1 x. r, c5 lMurmur3
& l3 l/ @+ L: k- d, G3 D/ z, s* [MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]1 `6 s( V& [$ j% Q* |. M$ |: Y
Murmur3特点
/ @( C8 c  C6 m+ w2 g$ l. B1.碰撞率低
; j1 r8 t# r( I2.计算速度快3 {5 n% N$ Z8 M2 z2 E4 u  Y& x
3.擅长大文件的hash
2 @4 q$ V2 ~& B- F( h* `Neo中如何使用Murmur3; {' O( ^& ^# v( J% b
1 Z2 S3 t' t; E: u: o: T- l
Neo中Murmur30 e0 d$ J* Q: Y  e' A( G
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。9 W) \& W4 H5 q3 W/ G
RIPEMD-160
5 a6 ~  F# i  t( M+ `( JNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。/ S1 N% v' F' q* _* X3 o. G; g/ y
// in neo-compiler/neo/neo/Core/Helper.cs
0 v! W) _1 h" f9 I7 d5 [8 P0 H) D public static UInt160 ToScriptHash(this byte[] script)2 ?% W6 R: J( [1 k" c* ~
        {, |8 F$ @1 q7 S, A! H* h, [$ @: E/ [
            return new UInt160(Crypto.Default.Hash160(script));
1 R) @& ]9 f0 U5 l5 j# G2 {% e$ d        }
+ u5 d9 H2 c% L# Q' B5 KRIPEMD-160算法的特点. ]) k9 S- n/ O! k# P" `1 `$ s
RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
* T7 v  ~1 s+ k2 V  a  o1 n! U加密算法体系( J3 X9 |# B! ?6 ^& v- l
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。4 G$ p; c( |/ o* [. {  @
加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。
* N8 J$ h- e: f+ W) x6 c解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。
3 b# X6 V! z1 n. Z0 X根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。5 }4 u" O8 g4 S+ t2 P9 D6 m
并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。2 t" m/ z' C+ Q/ Y$ {3 C8 U0 m! Y8 X0 u
对称加密3 _" U% x% T; n8 H2 A( w
顾名思义,加解密的密钥是相同的。2 Y1 x) ~5 G% l' T/ G! c% X
对称加密优缺点  W) w7 V! [4 t" r& M
优点是加解密效率高(速度快,空间占用小),加密强度高。
- ~3 h7 X' x' l& m. ?( X* b: g9 I缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。0 Z/ w5 Z; G- k0 ~3 F
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
9 N& \8 A1 ~- E/ R: _. t7 f. x/ z对称加密实现
, ?1 _: ~7 e4 `/ L" [- p对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。& u4 w; p6 s9 T( ?; w. g$ B, ~6 P
代表算法包括 DES、3DES、AES、IDEA 等。# X& ^- H$ s$ o
DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。8 w  H8 D9 D' ?
3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
2 e, M9 l2 B: a9 U& IAES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。3 b1 N& _! F2 K% g
注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
" _1 T: n7 Z) ?. B! \Neo中的AES8 f% L7 g" K4 y9 B
在钱包的加解密中,使用了该算法。! N) U& E$ V6 q
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
8 s" r! f1 P+ R4 B7 s3 O) H2 L, h" @
拿到私钥
- o% K2 Z5 p2 [& j具体的过程,后面再仔细研究分享出来。
8 r; n9 D% u/ W) A+ \, q, D8 ~( [% k非对称加密
6 u4 ~+ L0 k3 G, ~" J" Z2 S- v非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。4 F7 @" p; j5 R* B1 G; [. @
非对称加密优缺点; q2 E) |3 Q) n1 y
1.优点是公私钥分开,不安全通道也可使用。
$ R1 m% H+ T* N2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。
- t7 g$ B  I3 u! M8 R8 I* U; n& m3 L非对称加密代表算法
8 \& v6 v' s) o6 B, V# Z. o非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
* d6 O( I* v$ F代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。  v8 P( U' J9 Y
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
2 n  K3 S0 y- ]# O1 v- J) e4 i* h2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。
& j6 P- F: G; h, V5 ]. f* J8 t3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。7 z1 J1 h; }* l
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。
6 N' K# v! `0 R$ h; e' FRSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。* Q( w: e+ |( _5 `7 I& c
Neo中的数字签名算法4 y1 b* ^2 H$ B* u9 R9 I7 D
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。4 b$ b. X% D$ M* ^' F
public virtual WalletAccount Import(X509Certificate2 cert)
4 ~& `7 a  v2 p, c1 g: M) Y/ m" E        {
: Q1 b0 T4 q' d. p4 v; p            byte[] privateKey;6 B4 y- R' M. P' [! t3 q
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())- j* N2 W/ v( c5 Q$ L3 A* @  f
            {8 b/ Q) m5 H' G* `
                privateKey = ecdsa.ExportParameters(true).D;
7 x7 G2 R& ?( z, e            }3 b# V2 ], n6 z- A
            WalletAccount account = CreateAccount(privateKey);
* z- m! ]; [) `+ N            Array.Clear(privateKey, 0, privateKey.Length);9 t' i; O# l6 V! W; r6 K
            return account;9 A; O. i( v. t7 V3 ~2 W+ G* z$ t* ~- Z
        }
4 g2 `! `/ O0 [. H% T& U! IX509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
& T# E9 P8 G/ k2 G# F3 V( [' R( o总结
* b8 v2 F7 `7 N  P2 s% f8 u目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。3 U! y: o$ Y/ k( Y
参考资料
6 K3 q' b8 [2 t0 n( c区块链技术指南
+ N) n3 Y/ r! v8 J) b. QMurMurHash3, an ultra fast hash algorithm for C# / .NET  S% K" \# a; e: |3 P: \
scrypt算法的前世今生(从零开始学区块链 192)
9 L& V' s0 H# _, C9 }! j6 P2 b/ \Wallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3