Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
390 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。4 F) q! O* `- C) Z# C; ?1 ~
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。
' b' J7 D' o8 p9 e7 \Hash 算法- M* H* _; p# |
Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。9 F" h. u% s" E8 ?' h

: b" F/ W' m& i注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
! z7 k) O! G1 L2 C$ R' D- ^哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
. A, ^; \0 l& n8 J) i; H/ ^! _; n一个优秀的 hash 算法,将能实现:
' |6 o0 }" X( P/ v& d- {" |正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。
8 M) I, N2 ]8 i

1 w$ U. ]  S8 N( `, g: c& ]目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。; D3 }& _8 O+ R# r: m- k6 p
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。  i$ r1 K: i) j0 Z3 B
也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。# `6 X$ D' [& V3 ^
Neo中的hash算法
- m4 d3 [5 `7 q1 G3 u7 c" Gscrypt2 i1 ^+ m% N  U6 D" y7 z
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。! m! Y) v( |8 S  [# _: r
scrypt的参数
+ g, h9 ^7 P% ^, Z- t/ Xhttps://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors
  h& O' z  C5 M5 \1 Q$ wCpercival mentioned in his slides from 2009 something around
) u0 @0 A9 x+ d(N = 2^14, r = 8, p = 1) for
# Q; I( s  |6 k' D7 J3 dscrypt特点8 ~2 I) P2 H$ G+ n7 R5 J5 O
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。- z4 N, x" ]* N9 ~7 `
Neo中如何使用scrypt
" H' H4 L* c2 f8 ~6 n& m// in NEP6Account  q0 d$ E; c  z* D3 d# D) V+ D$ y
   public NEP6Account(NEP6Wallet wallet,
, F/ ^* M- b2 b' O4 _; g              UInt160 scriptHash, KeyPair key, string password)* E( \+ O+ [1 ~( K
            : this(wallet, ! n1 T( W$ S' Z& a
              scriptHash,
% Z6 d& ]9 ~8 W/ T              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
0 D, `; N, X2 O! i* d+ s        {
) Z9 O' `- u" W" c            this.key = key;
8 A" F* H2 |- K( L0 G5 @% w        }
& a6 u6 P: o' @9 K// in class KeyPair
2 S/ A5 f' y, b, V0 y6 R6 I6 kpublic string Export(string passphrase, int N = 16384, int r = 8, int p = 8); |6 D: S) ^: s9 b1 h" n) l/ [& y7 V
{* X7 M; i' o1 K, g
    using (Decrypt())  J: C5 a- q- J( B
    {0 L9 D; [/ X3 f5 B5 R
        UInt160 script_hash = Contract.' C/ f, F4 w3 t# F. e" M) P
            CreateSignatureRedeemScript(PublicKey).ToScriptHash();
+ n  U  K- M( u! P        
1 I2 @( c; `+ ]. \4 [, m, Z        string address = Wallet.ToAddress(script_hash);( Y& D. g4 D4 E, o2 f. f; k
        byte[] addresshash = Encoding.ASCII.GetBytes(address)
2 \. J) D" \% H  y: J- b            .Sha256().Sha256().Take(4).ToArray();1 o0 J# N9 M7 z9 {- ?8 ~8 S
        
& L+ {. w( @! U        byte[] derivedkey = SCrypt.DeriveKey(& f% o9 y$ X/ e% D4 m) Z2 K3 \. d
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
; v0 r) r1 M& Q1 A: C# W* E        
2 I  |9 z( S  Y% h7 j7 x$ j% c        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
& A' |5 j& x* l# b1 I, d1 V        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();# E) r/ u2 i" F+ O8 Q" Z+ `
        4 m" L4 O: k5 \* X
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1), i* M. @8 N9 ~8 _8 e
            .AES256Encrypt(derivedhalf2);
1 _& a- Y( D- H        / z+ x' d$ G* C/ s3 l* f
        byte[] buffer = new byte[39];! m8 `7 b1 a  N, k* l: k
        buffer[0] = 0x01;) f2 M( w, N( T6 @( I; Q) _
        buffer[1] = 0x42;
" o, G8 J! z. m' p; |1 V/ z/ T        buffer[2] = 0xe0;
* G. K3 {* J  |  U6 o! l        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
5 U2 F/ h9 v+ D# g8 p        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
8 X9 p9 }+ o$ c        return buffer.Base58CheckEncode();
/ m' F& H! V" j( A: ^. g/ P    }" K% R2 f4 f+ s6 }/ m/ t2 D
}8 ^. m+ U1 ]: i) [, e, m
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。) J) O1 r# `* E0 t* b
Murmur3
- f2 W: f# y! R0 R8 SMurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]: v# i. x8 X/ j$ h) ]) `/ \* Q/ W' j+ z
Murmur3特点' ^, o, R: @9 `- O
1.碰撞率低* T9 X1 {4 n- ]; y3 t
2.计算速度快* v; E1 L0 Q3 x) b/ f: v
3.擅长大文件的hash
1 r! E" c" S* }* C( dNeo中如何使用Murmur3
$ W5 u  d" e( T4 k0 _2 H: \6 _5 I. C2 M! t) r5 _, I* O, Y
Neo中Murmur3) k- H" q" M5 l2 I
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
+ _0 Z4 p! T% \) ]# j8 P# ^" R9 ]! ARIPEMD-160: P$ @, J2 _% ?) [' M% l3 d; ^
Neo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
( d; o0 K# K2 n) A% J// in neo-compiler/neo/neo/Core/Helper.cs7 N/ n4 n/ K; _/ E
public static UInt160 ToScriptHash(this byte[] script)
2 X3 {! p/ y+ p6 i1 S        {& P! [, @' Q( ?/ f/ H
            return new UInt160(Crypto.Default.Hash160(script));
( \. a1 Y, B6 q* @        }5 p- ?! a- [' `3 t3 @
RIPEMD-160算法的特点
/ s3 M3 }- S& X' g) T2 ^* e/ ARIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):* g9 {2 ]; R$ e6 D3 D
加密算法体系
/ N4 h( {" q/ a7 h8 c现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。, g* y( ~8 q; V. t, u3 D' v9 R
加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。/ M4 w9 W; R) T& `+ q
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。- v3 V: b4 T7 t& S* K% s
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。# ~% M0 U/ z0 p
并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。/ z2 A; M$ `/ w/ o. P2 C& r
对称加密4 R3 p7 ~9 K, I: g& i2 d
顾名思义,加解密的密钥是相同的。3 n, Y) e" L6 G: U; Z
对称加密优缺点
; I- W& `4 [- i, q* O优点是加解密效率高(速度快,空间占用小),加密强度高。
9 S7 L  j/ D! k缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。
' X) R; S- X- R9 G适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
! Q( H! b) j1 P对称加密实现
$ u; s' m$ V6 t/ [  c7 w对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。7 h4 f5 @% @# I3 `$ ~1 j& H- l
代表算法包括 DES、3DES、AES、IDEA 等。
5 q' |$ H  h) [  z- JDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
0 Z6 N3 s! }, v) r% ?: G6 c- E3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。  J) M  x0 K1 {$ e
AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。- H+ ^8 Z$ j4 d3 f, q
注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
; n0 I7 [4 D+ I& n( c3 E& t. vNeo中的AES
; A. m# ^% ~, s- {  }2 L$ I在钱包的加解密中,使用了该算法。) W' n+ C' G  S' s( f
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
! g5 W- x7 m# e0 G2 s7 }" J) v9 b& v  v5 D- Q" k& {
拿到私钥
. c2 v. Z. a+ n具体的过程,后面再仔细研究分享出来。
  B- b; F% ]) c* b& T; {1 ?非对称加密4 ]* _, x8 {8 T, E
非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。- A$ r$ n. p# k  d! i0 q0 e
非对称加密优缺点
( r/ T8 ~( H& @1.优点是公私钥分开,不安全通道也可使用。8 S/ L; z: h+ m6 ?. K
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。
* R& d5 z- Z0 B  @/ H5 h+ c非对称加密代表算法# A3 i7 s/ b) a) F
非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。& g) J  D6 X7 z
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。. Y: i& M3 |8 e  j$ G3 |+ I% m$ J
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。0 q* A* b# N6 X) i
2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。
, h2 a  a: J2 d  j3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。& S: O6 \1 m) U( }
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。
3 x6 Z' m$ A3 P0 `& Q* k* WRSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
& v: q8 L# }( T. g6 n$ _8 ~Neo中的数字签名算法- |3 T' b* w! r+ a; Y. Y' D" d; V
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。
+ k6 g! [" r- _% N  G0 @public virtual WalletAccount Import(X509Certificate2 cert)
3 k' y9 @, O+ z* \. s! `        {$ |# y' w$ C) q
            byte[] privateKey;
  W) n9 _& ^0 t+ X8 X# _9 o: v6 \5 @            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())5 N& ]8 S! @6 ^, x5 \0 d5 {
            {
4 ^3 d$ Q9 y3 C* H' D0 K+ q: e4 a                privateKey = ecdsa.ExportParameters(true).D;
: _# m8 L8 Z4 G1 o. e            }8 H( x; x9 [0 [" m
            WalletAccount account = CreateAccount(privateKey);
9 y3 z5 X8 I" p* V5 X2 d% @            Array.Clear(privateKey, 0, privateKey.Length);
9 e3 P3 `4 g# g. ~/ M6 X' q% w3 o            return account;, T1 f% Z) v9 n1 P$ k* l6 K' M
        }+ r  w2 u0 r* ~: a- R
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
  J. E& l! d* x! y2 G- Y总结
0 [) k9 W/ s( k8 g  t目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
1 Y- Q+ ]" f- p1 N! _# h: X) r参考资料" T+ X6 Y4 c; c8 m) {
区块链技术指南
+ L+ {0 k2 S; K( W$ \3 f, ZMurMurHash3, an ultra fast hash algorithm for C# / .NET% W; r5 }) f+ }: N9 A
scrypt算法的前世今生(从零开始学区块链 192)6 A  |, x2 e' \6 L0 w! S" _6 `% N
Wallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3