Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
474 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。- w5 x! M' L! k* a, e) p
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。, A5 {! Z0 u6 S4 E
Hash 算法
; e6 l7 Y9 R1 f) x' i& q  J+ uHash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。
1 n% ~( n; e: s1 y! L8 m$ p
3 ?! i2 [/ v$ n& A; q注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。$ R1 L  ^, a6 i2 T
哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
2 Y; G% S6 y% o: s% ~  m9 ^一个优秀的 hash 算法,将能实现:
6 K6 E7 y  {7 r正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。, e$ j, D+ g) {- n8 s3 @
: A4 N  J6 z: L1 L* l+ _) o; `$ C  a
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
+ I3 x: m1 n% d; \1 e, g1 i& i1 v$ I一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
6 J) U  L( Z/ g. k! ?9 p也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。, t) Z+ U& D; b6 f/ v0 [7 G
Neo中的hash算法
& P5 s8 k$ H$ q- iscrypt
6 |/ e. q5 Z6 s" q2 Lscrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。' V9 C4 L* y& R( O
scrypt的参数5 C0 G, k/ c% L! m; F$ H5 F; x
https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors5 J+ D6 |4 L% {5 V* Z8 m. a
Cpercival mentioned in his slides from 2009 something around* N7 x- v3 j8 F" g! @6 @$ X6 l* R
(N = 2^14, r = 8, p = 1) for
* s9 M: ]: I  j2 c* S" Y3 e( Rscrypt特点# j# h0 U5 }6 S
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
) b8 _$ w7 O3 w' j/ r8 R& `0 wNeo中如何使用scrypt: w: O. g& M% Q0 y( w0 n
// in NEP6Account
9 v1 A' B7 q- q0 c+ U3 }* E   public NEP6Account(NEP6Wallet wallet,
: K0 x- i3 Q% p9 U; h- ~              UInt160 scriptHash, KeyPair key, string password)
, ~% q/ t; i: |" g            : this(wallet, ( s& `. @" n( M& K4 K; |
              scriptHash, - o3 Y, ?* d8 I' \0 Y2 z
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
( ?; O& l& R$ r3 [$ T, ^0 \        {% {; P3 o4 j3 X8 a% \
            this.key = key;
( V1 ?% ~  Z2 I7 x        }# e# N2 ~& T" A2 l2 _
// in class KeyPair
0 q4 I, a) B4 |1 l* ?5 upublic string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
3 Q" T% [, A1 z- }6 n, j{
$ q/ Z3 \% o  E% X% L+ \; o6 o' n  y    using (Decrypt())
3 y: u6 q0 `, i2 d- c2 j; h    {' x% ^  M  C& F, A
        UInt160 script_hash = Contract.
- Z" _: \* R( D4 n# G            CreateSignatureRedeemScript(PublicKey).ToScriptHash();8 z+ W1 e9 W  Z  c# h, K5 }0 q& @
        
8 e( v: C$ u3 \4 Z/ D) K- F        string address = Wallet.ToAddress(script_hash);
* @) e- M4 N( i5 P0 d: t  i" w0 ^        byte[] addresshash = Encoding.ASCII.GetBytes(address)* d3 F: P3 \6 f  P: H9 V
            .Sha256().Sha256().Take(4).ToArray();
0 `. j9 V$ P1 y' B& S  i        
  P) _; o% {$ V9 u% z" ~        byte[] derivedkey = SCrypt.DeriveKey(
1 N' s! B6 T  j2 l2 e$ T& n6 y            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
% o# H; p5 b8 T7 c7 B7 X        % e& ]% d7 M! p- C5 C
        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();1 e1 f3 K- s: N: b/ G! U! s7 g0 o- A
        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();0 G- M1 \0 m* b$ G
        
) t0 O) F2 {/ T( C& B5 _        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)% N6 L0 F/ z8 Y& A( B  e* l
            .AES256Encrypt(derivedhalf2);
  j+ n' W; \+ `6 v8 |& R        ( z" D% g" o) P" _
        byte[] buffer = new byte[39];0 a6 o7 c9 ]0 s9 A0 ?& [6 x
        buffer[0] = 0x01;
; |" e/ n. J/ W        buffer[1] = 0x42;5 U% z" ]" l( _; R) Q, l
        buffer[2] = 0xe0;
- g0 C! ^3 v( L4 C! M5 D4 T        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);5 P7 ^" ?; E# x# S
        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);4 Q6 i8 ]) M9 q- B. b
        return buffer.Base58CheckEncode();
) J$ Z3 I+ M7 S& ?7 u3 X1 ~1 m    }
4 @% l' p5 K* Z6 q}- |4 E0 m1 g" |- {, V* _
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。0 F/ ^1 S8 j4 F" o
Murmur3  T: a; y3 M. W! q( L9 y" a* P9 x
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]3 r- R: f# G% B$ n$ u  ]/ r) k
Murmur3特点3 K" P  L/ j+ ]# ^3 X: t
1.碰撞率低6 b; J6 K: `2 ^* N# {  K4 _% \
2.计算速度快3 x& Y* ?4 K- O( s
3.擅长大文件的hash* C+ T1 o9 B, s/ M; l4 i
Neo中如何使用Murmur3
+ a  o# R( X$ D$ n& ~4 G: z$ M" b) g# y
Neo中Murmur3
4 R. Y. T+ I" v2 P+ x2 Y! aMurmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
" z! t" h+ N- M3 l+ Q; |" ?' [/ u  xRIPEMD-160  b9 v  Y/ w- [3 o% q
Neo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
7 I+ y6 m7 ]1 Z* ]) o5 J8 e// in neo-compiler/neo/neo/Core/Helper.cs( F) }, C0 C# V6 [
public static UInt160 ToScriptHash(this byte[] script)
2 Z' q# B) J1 l/ x! w+ o        {) r; Y; K5 N! b
            return new UInt160(Crypto.Default.Hash160(script));
) C0 a1 K* d9 |& {        }2 S% w. w3 {2 ~* ~$ ~8 O3 B$ u5 d$ a
RIPEMD-160算法的特点
+ b- h3 r$ l5 U2 X3 T! n  YRIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
% P* }0 p' @/ X* _  C0 }( Q: Q2 n加密算法体系/ r" D+ W, W6 a$ n$ N
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
$ e" X  n9 P9 ?% v3 E! C5 H. ^加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。
" W9 d' ^6 ]) H/ C3 N" Q0 }3 g解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。
# Y  ^, X, n& n- B根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
2 C& Q3 e4 @/ W1 h5 E7 {6 S1 A并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。
6 b" c7 L( p: Z' T* C% H对称加密
7 j7 ^$ ^/ x' V% d! k# {2 u: v顾名思义,加解密的密钥是相同的。; ^3 b5 G/ ^( y9 o' C1 t, E
对称加密优缺点1 @4 w8 Z( J' e2 s
优点是加解密效率高(速度快,空间占用小),加密强度高。3 T# ]! |0 l$ Q1 z
缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。2 P; |* @1 T4 ^
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
0 U, _& S* u( a: {& e  y对称加密实现
7 L/ p$ q  S  W9 Z2 ]4 p对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
9 J& p3 i1 E9 l7 H+ W* o/ ?9 t代表算法包括 DES、3DES、AES、IDEA 等。/ y7 a6 U& d$ I2 G! f! g% u1 W' F
DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
3 F$ K9 \5 T! Z% J  M3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
3 o7 [4 l8 |; e3 RAES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
) c0 D2 f0 S3 _1 d+ X注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
- D2 N' t5 d% a, ~% g1 ENeo中的AES
* o" q& V* ^8 m8 J在钱包的加解密中,使用了该算法。
3 L* B% K6 ~8 ^) ^9 e5 u下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
) ^( }2 K- @  u4 T9 ]2 h. E) i4 R* a7 Y7 s, H. B& ^: C
拿到私钥% S% F  @% b2 w5 J
具体的过程,后面再仔细研究分享出来。
* J7 d" i7 C% z7 _非对称加密
4 w7 S3 m* }) r+ ~* {9 e% T非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。
0 A( K5 ?* `8 \非对称加密优缺点# P' Y. L# k2 Z, ^' e
1.优点是公私钥分开,不安全通道也可使用。/ X2 P# R: D$ X0 ~1 X
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。  d# z) w! U: _( b) z) C
非对称加密代表算法
/ s7 R0 m3 F$ L/ O5 H8 w% Y: |非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
" g8 ?( Z  ~1 z, h8 i代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。" R! t9 P9 ]5 e" t% |
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
8 t) s2 y5 H# |5 J. E# l0 m2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。! p* Z9 r4 P; R0 q% c
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。/ ?  |, ~! r7 O) Q  H8 M
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。
/ U8 ]2 {( A9 ~, X9 Z5 CRSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
( P1 e! C( n' Z; j- @Neo中的数字签名算法
) W* B" I- |+ \. t/ H7 t在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。) O0 k9 u% y& E+ q$ X  w& Z, H
public virtual WalletAccount Import(X509Certificate2 cert)( G# x+ M9 e0 M: ^' P& R
        {" i3 n) @: t% L6 }- @- M; N% y
            byte[] privateKey;% g6 p. {9 k% c# r/ f
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
+ q$ s+ z7 x: m) o1 w! J            {
9 J' D5 I/ }3 t1 O5 {/ q, l' v                privateKey = ecdsa.ExportParameters(true).D;1 ]0 g& ?0 J* Y" p, p
            }+ l9 N9 h+ m: P9 [7 |1 _
            WalletAccount account = CreateAccount(privateKey);
" N" x- X! G5 _" G6 J3 E' [+ _) l            Array.Clear(privateKey, 0, privateKey.Length);: W; [- z! `) ~0 c: ^, A8 R0 U
            return account;) O- ~" V, D6 r1 ]* e
        }5 G0 q. l1 u7 h% s/ K9 |' M
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
5 Z3 j* Q, o' W) V, H; Q总结
* c+ G1 G! I2 f. ^: v2 D" x目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。9 w% _; @# y' X( P# [3 s8 M
参考资料
5 v; `/ p* A$ ?2 ?* z区块链技术指南
6 `4 x; j* Z+ SMurMurHash3, an ultra fast hash algorithm for C# / .NET
* Z% w) Z, M5 y; S' Q) k, W- y0 e5 Iscrypt算法的前世今生(从零开始学区块链 192)' K! J3 ~7 h$ D- I3 B, x
Wallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3