Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
472 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。- z2 e4 H2 G4 [/ q7 g
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。
4 S% Z2 \3 `1 WHash 算法% T" o: B. Z% O) m0 h% Y( G
Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。4 X. G* e, x3 }% L+ m0 |3 H3 J
' o* C% @& c% N, U' e/ k
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
8 ?# }$ R! U# \* L# U( a哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。9 c) s& _; K$ s6 V0 F
一个优秀的 hash 算法,将能实现:
9 y1 ^4 X6 W, E0 X3 l5 \6 U$ u5 z2 N正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。3 ]: ?( F& G* y9 ]

! I3 l1 O" X- |; A# y目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。2 q5 u5 h) _3 G6 {1 s+ Z' c
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
% @! d5 l. |$ W; N也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。
- {  C* f- L' R2 R- F) fNeo中的hash算法
' x( Z& {7 h8 N; ]scrypt
3 M/ a+ L; B  F8 S$ ~scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。) W% S* G8 m& E6 }) Y7 _4 _" d
scrypt的参数
, |  V$ T$ x& m9 T4 p( rhttps://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors4 r7 b9 J# R2 }
Cpercival mentioned in his slides from 2009 something around) r1 p/ @. v0 Q- s: d, s
(N = 2^14, r = 8, p = 1) for
' V1 f2 g) H/ q/ Z3 X( cscrypt特点2 ~) W5 q, l  P
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
; E6 V9 ~1 i  Z8 S" p9 D& LNeo中如何使用scrypt* h$ y  L1 |5 v1 v1 O
// in NEP6Account
: ?& c6 B( b: h' f1 T7 z& X   public NEP6Account(NEP6Wallet wallet,
+ T4 g% i! @# `  [8 R2 s, C/ e              UInt160 scriptHash, KeyPair key, string password)
- t% n7 l/ y" S; u% A4 d5 [            : this(wallet, 1 O8 q) S* z6 ?! Q; A
              scriptHash, - q* b4 H3 s, o) ]# n; E& K# _
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
- Y% z, f& k- u9 `        {) I9 i6 Z2 u+ W+ `* z
            this.key = key;4 s( V0 i+ c! I1 S7 {5 U
        }
' i, b' g$ Z: i) E% ]2 o. \. A// in class KeyPair
# {$ l3 O) q7 T; n, A+ i7 I- upublic string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
  u* E8 ]( V- u8 B8 k8 ^% L) q{
' k  L: H3 N! G: f/ o( H    using (Decrypt())
" ~+ I7 _6 J' B( a/ b. _    {8 N  E; U4 |3 q' x( ]4 U
        UInt160 script_hash = Contract.5 q4 r/ V# m3 G% \4 ]5 I& H
            CreateSignatureRedeemScript(PublicKey).ToScriptHash();
9 d+ J9 l( @+ t; [2 L- C1 c' O) d( ^        " r, _, j" L- ]2 ^( v! a
        string address = Wallet.ToAddress(script_hash);
; G9 Y& z8 u) d2 G2 G6 e* m        byte[] addresshash = Encoding.ASCII.GetBytes(address)  F( z! y% j5 A" E5 M2 t
            .Sha256().Sha256().Take(4).ToArray();
$ ^# m( B# ]: g# U; X: S" _, z        0 X! @* r+ v  u- T& P& n- {
        byte[] derivedkey = SCrypt.DeriveKey(9 j  g7 \, Y6 L0 F: K+ s9 ?0 Y0 c$ e% i
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
8 F& c* A3 |7 ~4 L0 F% K; C        1 A0 x5 W6 l" L, O6 }
        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
/ ]; Z* g  R8 \4 `        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
5 B/ b4 P* Q& ~1 {( L        
6 @3 v1 l" u+ G        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1), k8 C- f2 M' c0 S
            .AES256Encrypt(derivedhalf2);
0 U- Z4 a6 l( [# g        
0 n9 W' h2 |3 p8 P( B2 j        byte[] buffer = new byte[39];
) l7 p  k" V+ X% Y7 l4 y/ B% D        buffer[0] = 0x01;5 D( w% m1 a  q" O8 {+ B
        buffer[1] = 0x42;7 x9 c' x0 a) D" Z1 }( |* M( K
        buffer[2] = 0xe0;
  `; A" s  T: g. n        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
( D/ j. s: U' N        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
; |% V3 l# ?% ?        return buffer.Base58CheckEncode();
. P* f. r+ l) v2 `; p& o    }6 a$ b: C7 [5 X/ z1 z' @
}' e3 p% b* y. \& g
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
3 c, H! d* Y9 N$ o; _Murmur3
6 w5 v: V- o" J/ n0 W) U5 Y# y! nMurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]& }6 }, r9 Y: w4 b% x+ w
Murmur3特点
, A+ c& W! c# Z9 M, N. P7 J1.碰撞率低: H  s4 b  ^. w. s6 b) p7 K
2.计算速度快$ z: _8 h& G0 z. ]
3.擅长大文件的hash/ r  N5 x' s+ x
Neo中如何使用Murmur3
# e" ]2 v$ \' ]4 P% @2 d  W% Z$ u; C; h& p: Q- ]( f- b5 L8 e( L
Neo中Murmur3( c$ |% D- s# v% V) V/ y2 y1 o
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。+ u1 @0 X3 d0 F" ]: z" y4 ~- x* u
RIPEMD-1607 f' o* _, N: B6 r& ~
Neo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
' [% z: _7 r, T9 s' |// in neo-compiler/neo/neo/Core/Helper.cs6 M: J& ~$ N, A  f3 Y9 k
public static UInt160 ToScriptHash(this byte[] script)- r; S+ ]& |# C, p. M& q' T
        {
' ?/ ?) e  D9 i6 _5 Q            return new UInt160(Crypto.Default.Hash160(script));
" D% |/ ?% A: Q2 a6 S        }
+ V+ }$ x; }1 T! K2 M2 R* WRIPEMD-160算法的特点
. J6 b. I) v+ O" V4 D6 F' pRIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):- \7 N( H+ c: Y3 h9 l' b
加密算法体系
, [8 C- p5 ]- k+ x" S8 r) h现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
/ u4 w$ ?$ x+ E3 S. L加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。; G3 J3 i" M- O* w7 C) T
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。2 R1 p- X5 ~% n( h, }( k
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。+ F% Z' t8 j+ e6 z8 E
并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。3 O# S; }9 n& |: l4 I2 ~
对称加密+ u! [/ V9 E. i8 G8 {
顾名思义,加解密的密钥是相同的。
/ g% F' F% A7 q) w% u7 Y. ^; Q  P8 [对称加密优缺点/ U, ^4 l$ J; M$ T5 N" S
优点是加解密效率高(速度快,空间占用小),加密强度高。
" P4 a% _. P8 m7 x- ~+ u% ]缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。
4 n# Q9 n/ \* n$ S% ?9 s1 y* t适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。+ r( ]" L$ w  C9 Y- z
对称加密实现
( a" ~: C& W8 l" B) I& O对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
  `6 [" b* L9 _1 Y& A8 }代表算法包括 DES、3DES、AES、IDEA 等。
' |6 X2 M/ x3 F2 {& s4 `DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
0 P, @# s" x, u' E: @- W  D* G3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。. V4 i. E, {0 K6 v
AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
8 u7 b5 {$ ]' h+ E" y+ A2 N1 T% ~注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。5 Z/ _" v1 }# G- l) y  C
Neo中的AES
+ i" g# e) @! E在钱包的加解密中,使用了该算法。
, i! p, Q3 f# P, y下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。: I: a8 g' i+ U* Z0 X4 f! b! n% M& Z9 p
$ d. N' J  i; i7 \
拿到私钥
5 f, m/ j# `# O( {; O* ~6 E! T具体的过程,后面再仔细研究分享出来。
3 N( ~$ Z" J8 S: t$ g非对称加密
* U! H8 M" v! K- G; o, z5 g$ g非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。
) c1 g8 h, k4 W. w* V8 J% S# m- E9 q非对称加密优缺点7 ]4 o/ Z4 m* p" I  Q
1.优点是公私钥分开,不安全通道也可使用。' r1 u7 P' W) `$ z
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。
, J) w; O  T0 v/ U2 v. S5 a非对称加密代表算法! b' s3 l" I: y4 X- }/ o3 i3 L
非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。/ Y! e# }5 @& e
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
/ N. ~0 a) r+ e3 J3 U1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
9 H! t2 d9 w/ H" r5 w5 X- b. l9 {2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。! J& x( `% U) }: r* o% a
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。. ]5 _( H( |' E+ s* ^; L6 C
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。0 w3 h: P/ S0 o! o" U; b- U
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
4 `# r* K& Y2 S8 t# nNeo中的数字签名算法
$ [: R2 D" w( q在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。, w; j/ Q! z! \0 C5 R
public virtual WalletAccount Import(X509Certificate2 cert)( d2 }# q& b0 o
        {% N8 k' A" C  z' \  e- ^
            byte[] privateKey;
$ D* |+ ^( |: O2 |& O% o" _' ~            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())# v( F  H0 R) U5 u3 ^# E; ]% d& j
            {% ~: m7 T! J  J2 C
                privateKey = ecdsa.ExportParameters(true).D;
. u2 Y9 X! B+ @: _            }0 n( u9 s% v, H! Q1 g
            WalletAccount account = CreateAccount(privateKey);
2 c, t+ n7 l6 t& ]6 l3 g, {            Array.Clear(privateKey, 0, privateKey.Length);
! R9 A6 J' }% B: A7 R            return account;; f. N; a9 E3 [0 {' n  z( B: P; A
        }. F4 |7 P# @: ]1 \. W. f
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
0 z& \/ V1 e; K& z7 f* V" R总结1 K( @9 P( P1 q/ \4 E9 r& Z
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
0 W: g! X! C& j. d1 }参考资料" ]2 l1 k2 n2 b
区块链技术指南
  x3 V0 ~) N) M: t9 QMurMurHash3, an ultra fast hash algorithm for C# / .NET
! `5 Y: T# a( O2 hscrypt算法的前世今生(从零开始学区块链 192)8 r% t" H" y" g9 q$ M- u
Wallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3