Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
445 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。
* v& B, \3 P+ [. I: b关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。
! N3 t8 y0 @' C& UHash 算法( z3 h0 q( e- U* X- {4 m  Y) j
Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。; A8 H3 H, Y+ S. d6 ^4 K& l
; ^2 T+ ]% c' i! L
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
( ~7 e/ b4 m, x) S, E# X& ?哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
6 {5 v8 v* o* L一个优秀的 hash 算法,将能实现:
4 H& S( D& y; a1 `2 O正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。! V6 T9 x* G; ^
/ i/ w: }$ D0 G5 L3 l! ^4 y" f
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
0 z' s) [: L; M, i一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
9 S$ B" g. Z4 I" m( v/ h9 |; c也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。& Z: K9 o7 Y- p9 @# h
Neo中的hash算法
; r* |% ^# U# G& @scrypt
  i) c& p2 J  V" a% l* I) Zscrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。
) _' x) N2 b& d5 ]/ e& h- Nscrypt的参数- Z: U! K3 {; @' V8 N/ v8 T& x- z& @
https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors* g: E% ?1 ?4 P& o
Cpercival mentioned in his slides from 2009 something around  \; ?* [# x# `! o
(N = 2^14, r = 8, p = 1) for
: y4 E8 q7 A9 vscrypt特点+ V2 T8 T8 s8 @/ F; u8 Z- f
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
0 ~- K1 k7 d! z/ qNeo中如何使用scrypt4 @, E8 t, E- r0 Z" c- H7 C  D
// in NEP6Account
% I5 }% S8 _: ]6 G9 `5 ?6 s   public NEP6Account(NEP6Wallet wallet, ' _+ ~) N' h' x3 Z: N: w0 r& V) H
              UInt160 scriptHash, KeyPair key, string password)# V! I& s" c( Z3 z
            : this(wallet, ! o% l4 O6 d0 ^2 \" n
              scriptHash,
, k' m5 H- E: u# p6 @              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))) ~; A1 d& Z. p  P$ E
        {8 R9 w; l. r' S, L" W% @4 h
            this.key = key;- g2 Y" E  a* x" j. O
        }
! A" U7 A! W+ J6 T3 }1 \: E// in class KeyPair
, R4 h* m# }" D% _% }public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
' o# F. o" s! Z" `% S{) F7 G; u) R. }& k+ N6 ?
    using (Decrypt())
7 O1 e# Z8 n- N; M: x3 a4 }6 \    {  {8 f% c  E7 G! N
        UInt160 script_hash = Contract.
, [: o& f& g6 g' E# B            CreateSignatureRedeemScript(PublicKey).ToScriptHash();
$ f! P& n1 Y2 J% Y9 g8 z        # v; p; o& v" p- i
        string address = Wallet.ToAddress(script_hash);
( B* k; J3 [7 X        byte[] addresshash = Encoding.ASCII.GetBytes(address)
  j2 n  P6 G8 X7 c1 h; Q            .Sha256().Sha256().Take(4).ToArray();! Z. Z! k! h: e* `: t
        ! X0 }  R/ y" }3 X' o. W/ `
        byte[] derivedkey = SCrypt.DeriveKey(9 Z# r1 B! \' U4 A# ]) i7 h6 U7 w
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);8 J# U- `! C9 V; [5 V
        0 t% Y7 N4 t% f; G
        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
& S6 S2 X+ V7 b5 m3 w        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();: V" O  ^) d5 O; J9 |; o$ M& L% T
        - R' Q: G& p1 K# @# A
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
7 D) _6 v6 V8 p            .AES256Encrypt(derivedhalf2);. e* G8 |; p7 M$ M/ t& ], \+ k6 C9 i$ @: B
        
2 n6 y. H( o% H  O$ B5 u        byte[] buffer = new byte[39];% R. T% j, j/ e
        buffer[0] = 0x01;
4 E) r0 u( J8 w- H% H3 i5 G        buffer[1] = 0x42;
) v0 B4 K# @+ T! L$ n        buffer[2] = 0xe0;; h) p7 u$ X6 E
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);: Q7 Y# g% Y; o: @4 p) r
        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
% O# O: s! b2 R! r        return buffer.Base58CheckEncode();- m' ]! |% {4 n. l5 k
    }1 u+ Z7 U. Z! b+ b) d: P1 A
}
; G# x$ {# F0 P可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
+ ~) }; ?7 G, P8 {Murmur3
0 C, s; Q+ B: d3 r8 kMurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]
$ Z* F  B' e* A5 h1 C0 ZMurmur3特点3 O' v% u8 {9 L" o' C3 j
1.碰撞率低. m# a; b0 U& N& c7 X
2.计算速度快- H. k  n' Z+ a. b* n, c- b
3.擅长大文件的hash$ k+ L4 r% D; M6 v
Neo中如何使用Murmur3/ }* F* p3 m; ^% B/ S

8 |4 B; x. y* c0 mNeo中Murmur3% ~4 ]  X3 {) ^" B% Q
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
+ c, B) S; b; L' M8 P' A& eRIPEMD-160
3 Y6 ~7 u8 p1 d/ _$ \8 Z1 tNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。% b% Y0 m  B7 Q1 Q# U) i
// in neo-compiler/neo/neo/Core/Helper.cs8 I. ~; E6 K6 d' I, u1 H
public static UInt160 ToScriptHash(this byte[] script)
5 z& w4 {) y  [# C9 x        {) X* b5 p+ v1 H$ U- ]: n6 B
            return new UInt160(Crypto.Default.Hash160(script));
$ T" K7 [7 H1 V        }
3 _5 C3 t0 f) s) r) E7 xRIPEMD-160算法的特点& r* ~) B: V! T. ^& S- M5 g
RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
1 Q8 O( E" N3 k+ H3 t( @8 J加密算法体系3 p$ M! G. D; u& Q
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
6 I$ G  R0 K7 b8 W% ~$ P加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。7 b' m3 J& S0 g  s, o7 w' n2 t  S
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。0 x! I/ L$ b  @( O6 o" L2 Z
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。) ~8 g+ S2 f# F. \3 t, r
并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。) t: t9 s# C9 ~) h( d
对称加密
* @8 e- \2 \$ p. U" L顾名思义,加解密的密钥是相同的。
. `5 V5 g+ x0 e2 A. U1 \对称加密优缺点) l/ @" ^  f* s# W  `5 _' A
优点是加解密效率高(速度快,空间占用小),加密强度高。
- R# J* T* P. a' P) C# f缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。
9 @8 k( y4 @- A适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
: k1 K& n; U6 y% O+ O, Z3 ?对称加密实现
  h  n8 E3 C: L0 E对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。6 D1 K4 c1 J+ T! k
代表算法包括 DES、3DES、AES、IDEA 等。
$ r) D# v* v1 q) w" G/ ]( O/ S, NDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。; u1 Q7 m: O0 i8 Q
3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。' g. o7 u( [: U( K$ z. v9 `# v
AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
7 A  ^$ ]- e; }$ o注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
2 X, Q- l% T. e+ ~: NNeo中的AES
7 P, w& y2 h8 a3 K6 u0 F9 ?, I在钱包的加解密中,使用了该算法。2 u. h- ?8 J: ?0 K
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
, U0 ~0 w6 M- K. r3 L) i) a
. n. I7 i1 P" B7 b, V4 T6 V7 W( ^拿到私钥. X: r  a) e4 S" ~8 I2 z+ S
具体的过程,后面再仔细研究分享出来。
' G3 {  v) V, i, C非对称加密, X# h& v" X6 r' ~' G
非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。
! k6 r% x4 F% x* B- W8 o8 n: ?3 A非对称加密优缺点
, ~* l6 M( I# B; F7 q1.优点是公私钥分开,不安全通道也可使用。8 v; M" r9 l) M. i/ o$ y. ]& `
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。8 ]9 U1 P$ u" H& E" P
非对称加密代表算法
4 c7 k0 r; i8 ?. p: z9 j非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。* s9 B; N' ]( H# P) f: P$ h. R3 @
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
3 T+ g1 f1 |9 J/ i1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
# q& y  F1 b$ t- j5 t' u& v2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。  W5 y1 ?7 A4 _0 B  f  O
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。, Z0 g% }+ o+ n( D% i
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。! L* S# @" d% X! d3 m: {6 T
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
- _, F; H9 q5 e7 e* x0 A6 nNeo中的数字签名算法( @9 y1 p4 }6 x+ [  Y
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。
2 f8 s) ]9 Q" v3 a: upublic virtual WalletAccount Import(X509Certificate2 cert)
! R3 o& b, N% S: J        {
% p+ p$ r, h' w& L            byte[] privateKey;& w5 Y: H4 e9 b  V  F) ]
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())* L8 F2 z+ H9 `! p6 |7 `8 o( D9 `% Q
            {" J& S0 H7 {/ h7 ^
                privateKey = ecdsa.ExportParameters(true).D;
) ^$ R+ n+ X- _! c: Q            }; k2 b( k2 j( i1 m' F5 M' l+ ], a
            WalletAccount account = CreateAccount(privateKey);
3 @- r8 c* C( f  C            Array.Clear(privateKey, 0, privateKey.Length);
2 ?: F: Z! b0 C; q' b5 v            return account;+ j' @! k. Y. b5 C" |6 k' f
        }
8 s& n7 L3 Y) o' EX509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
4 D1 x! F9 O5 t3 T总结/ ^) b2 [  V7 W
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
0 [6 u( v! f; _! \; Q- i( r# _/ o参考资料
6 c" [+ Z. x( v区块链技术指南. D9 z8 I& z+ C3 S6 |- m7 t( A
MurMurHash3, an ultra fast hash algorithm for C# / .NET
, N4 T* N6 n' A4 F$ F6 [scrypt算法的前世今生(从零开始学区块链 192)
8 W: o! j1 e/ Q3 B; gWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3