Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
476 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。
* _; \4 ^4 r# Y; y+ J& f# G8 }关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。
3 F4 x$ ~+ T0 A9 c# e/ w5 M" r4 T9 rHash 算法+ i" e; [0 ?/ s' w6 E7 _6 _, U6 _
Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。
) a+ Z2 Q3 A8 S: c4 K9 s
3 U7 H: f8 G3 z% w/ i: I3 o注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
) H2 ^; ?. O# n( T. B* W哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
/ A' R7 ?9 M" Y, L6 ?! A一个优秀的 hash 算法,将能实现:
( v2 [0 T2 \$ f+ h" c0 Q正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。  S; y' H$ C3 R3 m6 f
. @( r* Z7 I; l
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。0 B" @& J8 b4 P2 V/ S- {5 L! }
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。1 ~4 m+ O/ X5 G: `$ E* L2 Y
也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。0 ?0 _% b1 ^* x9 U3 R  W% Q
Neo中的hash算法
* Q. {" ?! f5 c( u& _3 {scrypt, K. Z( M+ ?; }& N
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。9 w6 `: M% ~% Q4 W' v
scrypt的参数1 S* p2 G; X$ N, Y5 A2 Z
https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors
  m- Y, L$ {; m, ~Cpercival mentioned in his slides from 2009 something around
, b7 l  r- m; B, g+ M+ F. B0 @# U0 |(N = 2^14, r = 8, p = 1) for
7 I' j0 u% \) |" d( bscrypt特点' |7 x% a+ E* ~8 Q! J" }/ |, ]8 f
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
$ ?! D1 h/ o+ W: O" _2 i1 b0 h0 bNeo中如何使用scrypt
( S# ~4 B/ j( |" P9 V7 D// in NEP6Account3 W8 {, i" s7 T# B* e
   public NEP6Account(NEP6Wallet wallet, , T" G, o8 \, D& `
              UInt160 scriptHash, KeyPair key, string password)- P; u" a5 o# W. v; T! ~: K* O" I
            : this(wallet,
6 Y' `, N1 k1 _4 a' o+ b$ _              scriptHash, / Z. P0 v) t" a) Z
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P)). U2 e9 z; Z8 U  G) n
        {7 U3 ^6 S/ K3 K4 Q" G5 l% O
            this.key = key;3 j9 W, O6 k# g4 m- {, m% ?/ Q6 {  n
        }
3 @' A. Q. l7 z6 G0 q( `// in class KeyPair* A( G) ^' ^) i5 P6 F5 x" s
public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
/ e" R" D( i0 E% P! k0 c$ Q6 y{
. l: G5 R  q3 s    using (Decrypt())( E* W7 T; e( K" h/ |
    {  y& K; R; P) j% S: a9 {
        UInt160 script_hash = Contract.
# \8 {+ E6 b/ }) b6 y- R- a            CreateSignatureRedeemScript(PublicKey).ToScriptHash();( j+ u$ O' @! _' t
        
3 K( W3 O5 g0 @2 x        string address = Wallet.ToAddress(script_hash);
# P, f5 w! v2 v3 ^2 l! n        byte[] addresshash = Encoding.ASCII.GetBytes(address)
8 U, V5 ?- s$ A% E            .Sha256().Sha256().Take(4).ToArray();
9 |5 G: |7 x8 P, j. L% s4 S* `1 i" w3 a        
- m7 M- E/ w+ W, J. p5 m4 P        byte[] derivedkey = SCrypt.DeriveKey(
. o( v5 l9 R' G            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);- c! d, `' k1 }) M+ [# P4 Q9 R9 t
        
4 n: H' D8 |, B9 l  r        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();+ U. A& L& M% Z$ I" T# ?
        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
0 |' }' \) a( N! z        $ Y/ y; X0 w8 x; E: ]' t8 b
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)! H1 @2 h! p; @, T% [4 N5 k
            .AES256Encrypt(derivedhalf2);
6 p& a& A' x" H( V        ; _! F; u, l' ], Q6 n9 g
        byte[] buffer = new byte[39];2 \( W* A* ?2 Z3 S* b9 C2 M6 I! c
        buffer[0] = 0x01;
- G# r0 B4 _3 l        buffer[1] = 0x42;
. q6 c5 `7 s2 g3 s, u( V! \        buffer[2] = 0xe0;% B( h1 R' T7 X2 V) `
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);7 K" z9 Q2 m& b: _+ }5 d' x
        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
+ {" c- j9 `1 `7 W( e# l        return buffer.Base58CheckEncode();
! g# j0 c# V4 J5 N0 S6 x    }
3 L- a7 a9 `. V- V8 D' ?6 e! }}
- e1 Q' Z& i/ }+ k- q可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
8 P+ b. [. c! \Murmur3% b3 ?6 E' }+ E; M; c
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]1 v9 N/ A) d9 a& L! `
Murmur3特点# G" A& i2 ?# u8 Q  T- S! M
1.碰撞率低
; \8 O+ l3 |' z; e+ y% k3 a; ]& s' g2.计算速度快
& c1 x/ G( q: H1 X1 g3.擅长大文件的hash+ q% v. F4 s6 f* G
Neo中如何使用Murmur3
4 y! j# d; X) D3 F) }, {
; O& a& ?* b/ M5 R/ k- \- GNeo中Murmur3$ x- ]. w( P# a2 |! t7 v
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
8 I- c, C2 e6 x/ c/ DRIPEMD-160
9 c) `# Z5 w1 K( G6 r' DNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
7 \+ u$ k- y! _7 O. a1 B// in neo-compiler/neo/neo/Core/Helper.cs
, |/ t, t5 e8 ?3 ` public static UInt160 ToScriptHash(this byte[] script)
  q1 U' w5 J7 R; }, M7 ~0 T6 [        {& H$ L4 W* y8 ]  g( L6 L6 r1 q
            return new UInt160(Crypto.Default.Hash160(script));2 v! I/ K5 y5 h7 c4 m
        }) u7 k  x3 J* B) z2 ~6 Q
RIPEMD-160算法的特点
2 h% p* D' X) g! [, m& ]RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
9 v; ^0 e% i4 C5 W( |8 w- K. w加密算法体系
% @# ?$ s/ A1 K# p. ?现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
! K8 X- u* k* P/ ]/ u加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。6 P+ g, X2 f, U( J( w7 Z
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。
9 P, b. p" _3 B- |根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。1 d, {/ r+ r7 l% _5 G* Z3 I3 e8 e
并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。; i  t! Y) C" a% ^
对称加密8 A3 e8 W6 h: j* B" y2 J
顾名思义,加解密的密钥是相同的。
# G4 C" ]% j% O2 V5 s对称加密优缺点- e! r8 w, W3 t0 `/ L
优点是加解密效率高(速度快,空间占用小),加密强度高。  T# o9 k" K4 O% Y
缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。
& _1 y( T$ E( |% C适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
* _+ B' g4 f4 M' z* X- T5 P对称加密实现
6 [; _4 \: _: }( p对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
7 L) s* _4 }7 @3 o代表算法包括 DES、3DES、AES、IDEA 等。
. ~' d5 r; V- G0 A  zDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。, t) q/ X1 Z4 B$ @6 Q9 L
3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
! c6 ^+ Q# h+ y( x+ O, u  k2 JAES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
" v- {# ^. S" J注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
+ f. d! Y5 h% ZNeo中的AES
- q6 f/ {7 m1 |, G4 A8 F在钱包的加解密中,使用了该算法。  o+ l+ |; `$ o# x
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
4 h2 m9 X. Y" ?3 M# f& N* O+ {8 J# H0 ?+ y; a
拿到私钥
2 |( |/ X9 E$ n. P/ j3 @5 n0 l9 |具体的过程,后面再仔细研究分享出来。
' E" p3 F! j. H# P1 n& i非对称加密
! H! t8 T: J5 H0 C. L3 ]! L2 B6 G8 C非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。' V& ^) b* b. _: b# f
非对称加密优缺点& ]4 M( q- Q9 z3 [
1.优点是公私钥分开,不安全通道也可使用。( e& h3 b% O4 }8 W6 ^5 f; N
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。
  H8 Z: Q9 A3 g7 c% \# Q非对称加密代表算法
/ R% p1 F, ~/ p2 F: y" z' k8 U非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
' x2 i8 D6 l( f9 a. z代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。( z/ B4 c2 x0 l
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。5 L! N; E- L  t0 R' N& d1 P
2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。' [$ e: b* X- Y9 \2 o
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。/ ]6 G- `$ L9 J0 `* n1 B
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。
4 n* x+ s" {. S) z' k" HRSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
0 s7 S7 _' X: D4 ?8 @, V8 R3 [6 oNeo中的数字签名算法
, Z/ `1 b! s8 g3 p9 J9 D在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。0 }) p% `, o' ~. x2 K
public virtual WalletAccount Import(X509Certificate2 cert)& T/ Z7 A( X( ]$ n
        {
/ A' ^- C" Q$ j0 t- `1 M            byte[] privateKey;) a# b% s0 u. V  s. F
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
- _. x8 T9 l6 b; f: n+ N            {9 D/ U, R" ]2 {& H8 n# J. m7 n3 X
                privateKey = ecdsa.ExportParameters(true).D;
" g, P/ y; o) z/ P7 O4 m            }
$ A) \# a/ [8 s" r7 R/ B1 ?            WalletAccount account = CreateAccount(privateKey);. Q8 D9 k: S  ^9 }2 p( J
            Array.Clear(privateKey, 0, privateKey.Length);
: u/ i2 Z3 p& M3 \3 C/ n& p* Z            return account;) M; S: I) R0 P7 X+ z. k
        }
0 i: O3 S+ E9 `& l0 QX509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
  b+ I$ \0 m3 M( o. s总结
5 {6 C9 F; V& n# U9 Z, ], B目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
7 L1 h# C( M0 E+ `参考资料' H! s* [+ l8 b2 m
区块链技术指南* B, E7 r) y0 J8 j3 K
MurMurHash3, an ultra fast hash algorithm for C# / .NET
) N' X" c3 _9 }' t* ?scrypt算法的前世今生(从零开始学区块链 192)
8 o. E( M  P: s( n8 |9 \% S& W2 K( aWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3