Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
349 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。" k0 N8 d  ~1 L4 Q  |5 d: o7 i
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。1 t" ]; t% h- B8 |% s6 H& A& L
Hash 算法
- g& b0 v) j' ^/ C8 lHash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。$ r( u+ S! f$ ]( l: \9 W1 a- x
' y$ `2 f+ A4 Q$ s
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
" C% b) d4 i; e( n哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。. G/ e% q8 {, f( p# r; I
一个优秀的 hash 算法,将能实现:9 ]& U) K- ^' X. O( b
正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。# U( Q. d7 n, v! y% H7 q

0 c; ^% z+ a' p. u2 z& ~' w目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。$ t7 o8 V6 v- a  ?- U
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。9 {% I+ w/ \  S& a7 A( X. T. P
也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。) G$ i8 T# d; }1 I
Neo中的hash算法4 s! ~% N! X/ Y# d$ o5 Z8 |! m
scrypt& Y3 g5 B  ^& m$ l
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。; T" w2 \6 b6 O$ n: ]
scrypt的参数
4 c$ @$ U- k. s5 J/ A3 l# Y( Jhttps://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors/ f' T* W6 |2 S' U/ V
Cpercival mentioned in his slides from 2009 something around
9 Q& _; q# j9 `1 d(N = 2^14, r = 8, p = 1) for ( C. w, w, r5 I  [
scrypt特点
0 ~7 i7 J( A% k- h6 L  w4 oscrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
1 W0 W+ Q  v$ NNeo中如何使用scrypt
; V( V. a7 h) r% Y6 ~// in NEP6Account
9 o$ m& [* f- A   public NEP6Account(NEP6Wallet wallet,
" u8 S- `8 h* Y' ^; Y% X( d              UInt160 scriptHash, KeyPair key, string password)
/ v* k+ k) e' Y8 ~4 m            : this(wallet, 8 H* \- r  K  R
              scriptHash,
+ M! U  v& N3 z6 y7 i4 s              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))% u) R. ]* s$ ?+ i% o% g' ^
        {
! ^) R; [" A: P' O  m            this.key = key;( n5 r! Z0 ^' n8 t1 ^
        }7 ^7 v. ]: a' h; i
// in class KeyPair8 _# q! q# F4 T2 }' \6 x
public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
# A7 y2 f% P: \) G/ [{% s& n. C4 ]% J
    using (Decrypt())
: o6 z# E* p% \1 ?    {
9 c1 Y1 l- A2 F! i        UInt160 script_hash = Contract.0 b. ~9 u# I4 ]  Y% `8 g2 k- V
            CreateSignatureRedeemScript(PublicKey).ToScriptHash();* `) O. Z1 ~1 e% e' x7 B& [$ _
          \1 ?8 I4 K9 t4 j+ Y: e: ?
        string address = Wallet.ToAddress(script_hash);7 Z& `  v5 e6 k  _
        byte[] addresshash = Encoding.ASCII.GetBytes(address)
/ H! |2 @' ]5 f7 l, d            .Sha256().Sha256().Take(4).ToArray();9 T4 I; C$ Q) f
        * \* m: q; `' S- m. w: _
        byte[] derivedkey = SCrypt.DeriveKey(
, _5 l* C, m& T            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
# T# e. V9 R! i5 A. o+ u5 Z. V# u$ P6 k        
' Z( R+ `0 R7 P: v% Q1 p% J" _- v        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();3 P# I- Z( ^' }3 K2 D
        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
% P* v5 t7 m5 W& ^8 W        5 ^2 r- g+ C& V' f# c
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
* }) u2 e9 Z$ d            .AES256Encrypt(derivedhalf2);
$ P# M" w8 v0 {6 w        , s9 \/ P1 z# f8 d% Q
        byte[] buffer = new byte[39];
1 ~: }; Q$ L+ u+ K        buffer[0] = 0x01;" d8 O* ]/ J2 ]' ?& Q" Z$ ]" f
        buffer[1] = 0x42;
1 C$ A' ?1 V, a8 l9 ]9 ~  Y        buffer[2] = 0xe0;5 T# v1 O* |5 q8 {7 D0 Z" ]
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
; [5 B) S& S. U: F5 y0 p        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);1 Q  |( _' f0 }. m. M8 |9 U4 V, i
        return buffer.Base58CheckEncode();' Y- E3 {+ c$ l5 W9 d
    }
( a+ T& V1 n5 ]# R7 v$ H7 ^# N; d}
  w' D: G+ ?- \  W2 E2 H/ u可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
. p4 c/ m; f6 I( A/ i' sMurmur3* _3 U: [" V* }6 m9 F# \- {7 M
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]' c6 [$ O5 K' j6 T
Murmur3特点0 T2 Y6 F. H1 \; ^0 x& U
1.碰撞率低0 b7 m, \; ^0 ?/ ?' t! R0 u$ B/ p
2.计算速度快
( i# S# n3 j. X" ?/ A0 U7 E3 t. f3.擅长大文件的hash8 d  K4 T' R4 ]$ f" s) B
Neo中如何使用Murmur3* B' k2 G0 g( X0 |- P# _/ h9 L0 H$ h

6 q, Y) D$ \# a% I+ I2 JNeo中Murmur39 G; q5 p0 f/ I0 \2 T
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
- u7 i+ Z! D" Q/ ?9 H0 IRIPEMD-160
9 z# i- N  ^/ B# P. KNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。. q4 i3 |8 u% x$ t! l! t# n
// in neo-compiler/neo/neo/Core/Helper.cs* ~# ?/ g0 l' h  d3 P0 [8 R: G
public static UInt160 ToScriptHash(this byte[] script)
. e* t; s) A! Y1 ~# s        {5 T/ h' e# _) w8 H2 u1 M
            return new UInt160(Crypto.Default.Hash160(script));7 u0 @2 y9 U1 m% e8 w, M, A+ |% S
        }" A9 a8 j: J% G! z0 x) U# C
RIPEMD-160算法的特点$ c: y2 M( b# T6 v% B
RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
+ }9 V& W4 Z% l7 Y' z$ J0 k8 i0 i加密算法体系/ S# `6 S$ p* y: ^
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。  i% Z1 e' j, K, a+ f, L# f" T
加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。
3 F$ ~5 i8 U8 m解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。
0 ^4 X. k) X' n/ L) O根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
( n8 P3 ]! C' Q并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。+ L0 \( |/ `+ K" ]4 ^
对称加密- X1 \# e+ R7 c7 ~7 [5 `
顾名思义,加解密的密钥是相同的。8 s7 @0 J! i7 [. n1 C5 X
对称加密优缺点
" P- E% K3 K4 I; c# @# Z优点是加解密效率高(速度快,空间占用小),加密强度高。. t- q* Y1 [( d
缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。0 x: Z/ \4 ]% V
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。' O' V7 u! l  q7 `5 e! t5 H
对称加密实现8 e6 D3 ]. B% A- E! P
对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
0 J- D& O$ ]& }1 U7 u4 f4 Q代表算法包括 DES、3DES、AES、IDEA 等。
2 f. l' X3 ~6 CDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
- v/ S% D! ~! K$ G6 z3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。. E# O, o/ `, R4 u, Z
AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
0 m3 v$ L/ p3 i( h, R: P! @1 G5 S; i注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
  l2 d8 O) i; v. Z- ONeo中的AES
5 _% h1 T# x2 K- V# N6 U: M在钱包的加解密中,使用了该算法。
* b1 i! p* m2 `下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。/ o: [% S" L* j9 @6 w/ R5 F* G1 F
/ f' h# M% _5 ~4 |! @4 k3 G
拿到私钥
! m- Y1 P! I4 @) F$ l3 a* C具体的过程,后面再仔细研究分享出来。
. r3 f: Z2 D1 A+ N$ z  U非对称加密0 C! T- J4 U5 }+ a
非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。, }8 @/ z. S, D0 _/ Y
非对称加密优缺点
( J6 _. t; ?/ X& B! R5 m: M1.优点是公私钥分开,不安全通道也可使用。3 B3 m0 A2 N8 U; }5 x0 }/ `+ @, w
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。
& }7 W. D" u; p, U! N" [非对称加密代表算法- M+ Y) u+ F2 a' z
非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。; w. ~0 D6 q7 c2 p
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。+ v1 j! q4 Y' u+ ^
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
& Z& E' c' h/ O! p8 Z2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。6 j" }' C( N8 a
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
& @# d4 o0 z* i- j3 R% h4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。( u" \0 W  k! {7 W0 S
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
8 ?& F, o+ Y% a+ q' lNeo中的数字签名算法
4 x4 O4 `* v% K, F- Q& p0 S在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。
3 Z3 _+ f! `( k! t' ^& R( Ypublic virtual WalletAccount Import(X509Certificate2 cert)1 X% ?* k# w3 b. e3 ]
        {
- p, A. D, d" y% N. ]- F' Z6 f            byte[] privateKey;
+ I1 j# O5 T" w- m1 h5 H            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())  b6 V# s3 U2 q! s0 x- u% p8 m- f$ R* }: V
            {+ P. t( b: n8 W( c
                privateKey = ecdsa.ExportParameters(true).D;
2 Y7 r1 {+ d( }3 I+ ^" h/ i            }
; H+ {" B  P$ I            WalletAccount account = CreateAccount(privateKey);% `! K3 e2 D* n  y5 C9 m. ^: C. `: {
            Array.Clear(privateKey, 0, privateKey.Length);
" D/ l7 X0 e" x0 k( C! {            return account;2 M, F/ H1 Y; H7 k
        }& N9 ^2 Y& r  S2 X8 R' O2 L
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。% K$ X9 T' U2 L3 w
总结
- [3 [2 r( d3 Z! Y3 u  j% u4 b9 Q目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。$ {, e' D, c  f6 y. x9 l
参考资料
1 }1 R) y, M5 ]5 d" E6 J区块链技术指南
' u) ~' o, T, ]6 `' k, s5 F8 l1 VMurMurHash3, an ultra fast hash algorithm for C# / .NET
6 L( H3 l, q7 D3 ^7 r9 V+ q: y* ?" e# nscrypt算法的前世今生(从零开始学区块链 192)
# G1 h6 L7 A8 SWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3