Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
151 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。) n7 f7 A: x! o6 ]/ ~4 p# g
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。
2 A. a( C8 X0 R9 P5 N$ U1 H7 DHash 算法. t9 F4 C: g# J$ H& l' L0 T
Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。
' [! M7 G, W/ P$ N- r8 ?7 G4 `4 N: `# i% G* ]
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
! J1 ?5 ?3 m* M哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。% ]1 ~$ z4 x, e( @
一个优秀的 hash 算法,将能实现:# }7 t1 \9 }0 M0 s
正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。
) L) _/ |7 W# @
9 N7 e; [  o3 A$ S0 m1 l, E2 z
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。$ w$ x# o: N: M
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。$ a. X- G  d/ X/ E  \( G
也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。
4 F& B; K- n, `; t( q4 ]Neo中的hash算法! A! d) ?: S, |# C$ T
scrypt9 f- z+ Y/ i( ?9 N* C1 P
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。
: ?: s6 b, M  Y) s% E( iscrypt的参数7 I5 |8 b+ x: {6 v2 |# J
https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors
) }; G1 W6 M/ J4 G4 _" R- @9 BCpercival mentioned in his slides from 2009 something around
. ?$ q/ R, B; {) y(N = 2^14, r = 8, p = 1) for 0 w1 N1 D$ }( x1 i0 f1 W
scrypt特点/ M( F5 A+ {: b/ {5 s6 F
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
& ^) ?& m: E. a6 @Neo中如何使用scrypt
8 G+ c0 Q0 {/ N+ u1 S7 `// in NEP6Account
) G( z4 Q+ ?- ~   public NEP6Account(NEP6Wallet wallet, 5 E% n8 ^8 T/ g5 l+ }, F
              UInt160 scriptHash, KeyPair key, string password)5 H& x, M2 R2 x* K  \
            : this(wallet,
; w7 H+ g3 R2 t  z* G: [$ W5 H              scriptHash,
$ D0 ~! S8 q5 C) G" ^, c              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))1 H# \. t7 I# t7 W7 `6 t5 I- k( u; Q0 z
        {% l; F/ Z9 P9 ?/ L
            this.key = key;* C' f. [2 ?  C5 J6 |
        }5 ]' [) E4 V; x. M6 J
// in class KeyPair
6 \; H6 [! R% f& ]public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)1 E3 D- m' S' ^5 W5 u% ?, B% K
{
9 h0 p3 u" s! H  C) ]8 L- @$ c    using (Decrypt())
+ E7 |" {1 f9 `; T. ]+ a    {& J4 U/ D3 I3 j: \3 j5 W3 i6 Q( _# J
        UInt160 script_hash = Contract.
8 \) b; E) M: k, ~$ @            CreateSignatureRedeemScript(PublicKey).ToScriptHash();+ X9 C, G6 i) ~) N4 n  B
        
. E$ x3 c0 Y9 {8 Z, x( X        string address = Wallet.ToAddress(script_hash);$ g8 \5 K9 b" L8 ^8 H0 G* S
        byte[] addresshash = Encoding.ASCII.GetBytes(address)& [! f* Z: b) M! e# {0 t
            .Sha256().Sha256().Take(4).ToArray();
) I) a  ]5 _4 `) k: o( M. D: [        
4 N5 m2 L6 e- d- |$ v. y        byte[] derivedkey = SCrypt.DeriveKey(
" X' {  e8 K2 G            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
' E! G6 `9 U! y, R: q        
5 f7 j9 R( M: ~, G+ v( g        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
/ \0 `( b- p: O' _3 A' M7 D% j        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();. p1 }$ H% J, C9 I" E+ @
        
/ Q& v- [: \! i" K8 J2 v        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
" V% g! O  o& i8 C7 N( K2 ^  P            .AES256Encrypt(derivedhalf2);4 [# g& j- v4 N* Y
        
* z6 `+ N! m: Q$ _$ P/ F) H4 M        byte[] buffer = new byte[39];
3 W+ ^- ?* k1 f, T        buffer[0] = 0x01;* u$ n  e6 \& S" _" |# `9 A# c
        buffer[1] = 0x42;
/ \. j8 @- u- r$ F7 U        buffer[2] = 0xe0;
7 e6 J; X( @4 d  U        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);. q5 A8 A. t5 R# ^/ g7 F
        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
3 X2 g0 e6 a7 I& P0 U5 U6 ?        return buffer.Base58CheckEncode();+ M" a. m2 g: l" N* E
    }( {0 c& \' O4 Q+ Q0 f" f6 Z+ x
}, Z7 t# o$ F( i! L* E
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
3 m" L3 }: I0 u  e3 u, @9 vMurmur35 K1 w/ W/ {) e: D; H1 G. x4 H
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]8 I9 b( P0 x7 M! [
Murmur3特点# O' r5 B& `; J" H" ^9 k. n6 y
1.碰撞率低
0 l" R, V1 Z: d2.计算速度快
4 x! j& S/ i( L4 P- Y0 Y0 T+ |3.擅长大文件的hash
1 I0 _5 z9 [! \+ U- {! P5 ^1 J/ g3 @Neo中如何使用Murmur3
8 S/ j& @6 K6 W) h% m5 T/ M" A+ F  k) [
Neo中Murmur3
) @+ f9 d5 g0 i7 R  z4 SMurmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。) T1 B, E, t4 k5 C+ i
RIPEMD-160
7 K9 _* s3 v$ x+ kNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。5 i& u' e- z5 Q5 s
// in neo-compiler/neo/neo/Core/Helper.cs1 E; C' U9 I% {% N6 {+ Y. z
public static UInt160 ToScriptHash(this byte[] script)) o" o3 Z: k0 c( S
        {) F5 v% s* k" Q" j4 V3 Q8 A
            return new UInt160(Crypto.Default.Hash160(script));
! }& o3 W4 W' Q/ e        }8 S( L5 G& \2 i
RIPEMD-160算法的特点' n* k$ O' r! \6 X  k* Q& Z% E$ C
RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
7 D; X( f- K! Q$ R4 ~+ S! e* ^7 P6 L: X加密算法体系
5 A; m+ g- P  O: [, i$ _现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
. Y, m3 n5 ?. n: j4 @0 T加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。
' }: Q6 }- G" C; M, ~; w4 X7 ~解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。* y3 M. ?! }4 o$ L3 k% m6 g
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
( E  b% Z. E) W: k并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。
) P" |5 H5 K5 D: @对称加密
% a7 E. j5 j* e8 v顾名思义,加解密的密钥是相同的。
2 X% W% }6 K! U5 w对称加密优缺点
) t! z8 B% m/ l7 i优点是加解密效率高(速度快,空间占用小),加密强度高。
8 n/ G3 Q8 M+ Y! A# z缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。5 |1 r4 f7 W" N7 u5 ~
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
# T! b7 n+ [& C$ q2 Z! N对称加密实现5 z5 b1 U; i& Y, l1 s2 ^
对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
7 I. V4 t6 o" N+ r  ?: f' p' [代表算法包括 DES、3DES、AES、IDEA 等。" p/ V; U& B5 c- H& ^: G: k' ~; \
DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。$ |% L2 c; b+ b, |
3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。. g& w  P  V8 d5 ]1 ]: ]) f9 i
AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。* e( V& ^! S& ?
注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。; M9 T5 S+ ]2 B6 C3 q# V  n
Neo中的AES
* l: a" V, ~. L$ x: G% e在钱包的加解密中,使用了该算法。) O. Q' n- r5 s
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
5 g, ]8 N$ b: P/ z7 E$ i2 ?! S; B# x7 i4 _, |
拿到私钥/ X4 P7 f! d0 k& ?7 j, M; G2 g9 L* z
具体的过程,后面再仔细研究分享出来。/ E0 v/ E9 g: Z) j, `5 Z( y3 i1 G
非对称加密
9 x( I$ T' C3 N非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。4 P. J8 A! W6 t$ q
非对称加密优缺点
! ?& ?: P% k+ h2 A8 l1.优点是公私钥分开,不安全通道也可使用。
, |# I' w3 d9 n% D2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。; J& J6 R2 }. n4 r
非对称加密代表算法
7 V% D4 J- \/ |% }非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
4 ^. g$ K1 I5 \代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。0 T1 z) o/ |) m9 A4 i
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。9 |. U: L- z+ u8 S( Z
2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。% p0 T  W5 s; p3 e
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。: T- m. Z7 P* ^# ]. e
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。- L7 s! X0 P8 N. m( b3 v
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
7 s9 ~( Q3 n' q" O: ?% B. KNeo中的数字签名算法+ \5 y  i. X# Q% S3 w
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。
) h* |! A* b* d+ b7 j5 Q& upublic virtual WalletAccount Import(X509Certificate2 cert)
2 w; G% H2 @. x. ]( |        {7 G0 t* h7 `! m$ Q. R( @/ i
            byte[] privateKey;
" B7 Z. B5 c+ Q! Z( X! H: X            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
  v# q) ~( D3 j8 w; S5 |; m% h            {0 {! ~0 s- a6 ~( E& U9 |) P
                privateKey = ecdsa.ExportParameters(true).D;8 D, C+ R. Q+ K/ @4 k
            }8 K4 F0 h+ i6 y: Q' |! Z) W9 O
            WalletAccount account = CreateAccount(privateKey);1 Z3 O! ?1 T3 B& f3 Q, O
            Array.Clear(privateKey, 0, privateKey.Length);
  b0 [/ B$ v& J% Q% \" i6 o+ E            return account;
/ N9 d) \) W* p8 ^0 s        }# W2 x  v# e3 ?4 Z
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。& n/ G( S  n) J8 k& S9 f% ?
总结% f# L: y# n. c
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
  T) b) w) Z% ~& m; @参考资料4 c: c8 y4 s# B8 |' b8 `' o
区块链技术指南5 x, A& v: `# r3 M% f  S. C2 ^
MurMurHash3, an ultra fast hash algorithm for C# / .NET
# H0 R( Z8 R1 l' T; D+ s* U+ dscrypt算法的前世今生(从零开始学区块链 192)
/ P- v& `/ y: N& g( i7 @Wallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3