Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

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

8 S- ^, A- S8 y9 N' ?目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
" L( k$ P# L& G/ [1 E7 T% m) Q一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
. H9 f  H3 h. J  D% V6 O  t也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。: P& o4 M+ a: C6 c  Q6 v! c
Neo中的hash算法
6 `8 o5 z* E5 e+ ~6 H8 escrypt
# L6 e$ I7 u" c0 i" Fscrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。8 u5 Q- Z! v# Z- Z3 t- ]
scrypt的参数
+ J, b% h" I3 I+ ]https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors
% p5 q% A# F! I- {! `0 T! Q7 z. OCpercival mentioned in his slides from 2009 something around
% A& H+ l: \; S! V(N = 2^14, r = 8, p = 1) for
, F: k4 O3 Q0 B* |8 X# X' f) Tscrypt特点
1 l6 Y) z! g9 j, Yscrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
+ m# F/ J  n( Q* n0 ?  ?( QNeo中如何使用scrypt
9 s$ W# M( m  Q// in NEP6Account
# R7 }7 m" s; i0 O- x   public NEP6Account(NEP6Wallet wallet,
1 W+ _7 K9 T! L7 u              UInt160 scriptHash, KeyPair key, string password)3 }6 J+ F, C/ z# G# R; P$ [/ Q4 p
            : this(wallet, 4 Z  N  Y2 ?( e5 _
              scriptHash, ( b  s) r6 S5 E; n, A+ V: m% Y
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))+ P. S+ O. v$ A; m7 `4 e
        {
  Z1 t, k# {8 }3 H1 I0 {9 }            this.key = key;$ D, Q; |* a# P% q+ i9 T
        }
/ t/ z0 s% H/ i) M$ Y// in class KeyPair
3 p, x- W; [- u( ^" l6 T8 Y, lpublic string Export(string passphrase, int N = 16384, int r = 8, int p = 8)3 O6 [  u& [: @2 m
{
; x& m3 r$ j4 J2 [  _    using (Decrypt())
8 z0 Z+ _. S3 E6 H8 S    {% H/ n- ?1 O( ]
        UInt160 script_hash = Contract.
0 G, J  m0 `% B1 N# w* l2 h; r$ c+ V3 o            CreateSignatureRedeemScript(PublicKey).ToScriptHash();
* G" P( @4 _: N' a        
2 g4 w$ f9 s* p( P) m. g. D$ ]        string address = Wallet.ToAddress(script_hash);! W( _. }. ^. I6 R
        byte[] addresshash = Encoding.ASCII.GetBytes(address)
/ ]; U  ~6 E) }7 h: H; s( p. d1 s            .Sha256().Sha256().Take(4).ToArray();
7 W& b: c% S" K( M' e3 W        + F* ]$ J9 ^, q2 A; k; E
        byte[] derivedkey = SCrypt.DeriveKey(+ ^) G1 K. i( O
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
6 u6 H; U" ~# [; e. @- X        
* ^4 ]$ Y2 q, [$ Z  O        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();
  C- J7 u) C7 s& e; \9 ?3 d        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
- K  U& u- ^- ^6 B% b9 b2 B        
1 V! A. I) Y6 B$ H6 E( K        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
. ^' ~: w. ~% P( b1 Q& |2 H: Q& E) A- u7 r            .AES256Encrypt(derivedhalf2);  U* O- X* Z7 @- |6 h1 C5 f' S
        
% p  ~- V& Y+ @% ^- ]        byte[] buffer = new byte[39];
* U5 W+ s- M6 x. C3 [" e/ v        buffer[0] = 0x01;+ i/ r9 x  P4 l& N5 E
        buffer[1] = 0x42;
/ e, N6 N/ X" o- b( d: X3 j% g        buffer[2] = 0xe0;" {+ w# W) ?% b0 ^7 K9 {7 p) C
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);6 T! G  O/ v3 L( t. J
        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);% y5 D5 Y, K! F+ ?$ B
        return buffer.Base58CheckEncode();) J4 n7 z# W% `- A8 ~$ x
    }) K, N+ t  L" @1 t6 j
}( U. b: H; O; K3 W  j3 P8 C  q, E
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。% I: J; |  Z  ~9 Y
Murmur3
' @2 n# A# |9 q2 DMurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]
, F. I) f% L6 ~% ^" f( _! ^- o* d. IMurmur3特点
1 g0 y& ^5 e# e* ]* x1.碰撞率低6 c  v+ J  ^, d) z
2.计算速度快
5 G9 a, K6 l4 c& f; @9 e, }3.擅长大文件的hash1 s2 ]2 O6 u+ h% _
Neo中如何使用Murmur3
* t( p9 s) q3 a3 j, e( i
2 x% f! G8 ~& U+ VNeo中Murmur3
' a" \9 V) t: e3 L0 w, {Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
* s: w7 D2 b1 YRIPEMD-160
( O- f, L, D' INeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
/ X' \$ S# T1 x* k// in neo-compiler/neo/neo/Core/Helper.cs) ]6 I% U9 F6 O9 Q$ h! {" p% {
public static UInt160 ToScriptHash(this byte[] script); W! N2 Y3 X1 }* N2 E9 v: J
        {
1 @8 }4 [4 p3 Z& c( o& n, c            return new UInt160(Crypto.Default.Hash160(script));
4 V; X, T! Q/ {* o- {! I        }( c4 L* R8 B3 ~  G6 k1 K0 ?5 N5 \. Z
RIPEMD-160算法的特点
; h( J9 k& m1 h! [RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):  w% g# E* C" z
加密算法体系" j+ S; U- E- o2 s( I
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
" J" V8 A2 s+ o* _加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。$ @9 D/ ~% V& O8 s
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。
, I6 j2 K  E. _3 g+ l/ [根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。/ U, J! V0 L& }( G3 }
并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。' p) C( t- g; o
对称加密
( x4 @7 _' t. V) }, k( g4 }3 R2 {顾名思义,加解密的密钥是相同的。  k  o/ q$ E  C5 R
对称加密优缺点* @3 S$ G7 \9 H9 F% u) X
优点是加解密效率高(速度快,空间占用小),加密强度高。
6 S2 p  e% b6 E' J5 F$ z缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。6 s2 H) J- R" y" N- A/ p
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
5 [& o, n( T$ d0 @% ]" J( S对称加密实现
$ f) e8 {& }' t) K8 \. c对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。8 G, A" v" n; J, u5 }* E' Y! Q! y
代表算法包括 DES、3DES、AES、IDEA 等。
  ?7 ~. h. M3 v1 {4 }$ p& yDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。$ K+ e* G9 n7 y  _7 f* L* M: o2 n
3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。' V9 P$ f) l1 L5 O5 b, H. P
AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
% S0 ~* U4 M. g/ m/ L3 ]: \注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。8 x+ c4 h3 @/ g  J3 a
Neo中的AES
4 H3 C2 q5 R5 p: w% l在钱包的加解密中,使用了该算法。* D" m8 {0 T3 r9 D5 u, i. u' N
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
; K. r" c/ l6 j4 U7 O
. u* X1 t- }& l, \: d拿到私钥
+ i  Z4 L9 p$ g9 T( p2 D具体的过程,后面再仔细研究分享出来。
7 V$ D0 Q' j' _非对称加密
4 N+ S0 y; [5 M' x非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。' B1 S: L( L( Z- J! K- ~! O
非对称加密优缺点+ d- Y+ @* `  m. \; p1 d1 z0 B& k
1.优点是公私钥分开,不安全通道也可使用。7 L( q8 e4 p3 j! \+ G0 L% {
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。! P( R$ ^( k: a2 v9 R# V
非对称加密代表算法
) Z) b8 B6 V9 _( G非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。1 \& x: F% e. p( \
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。5 p% j; j7 F7 d7 O' c" z. S0 v
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。' z, m5 P0 @! ^( ?: H6 J& l
2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。  \0 \3 c" {  G3 c: C% D- d
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
- b3 _$ ]: j/ j% |2 [4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。
+ s( B+ C+ c: D/ _- J. v# N% QRSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。( C. n- }$ y; h, X( e; ^: D
Neo中的数字签名算法9 K& m3 s3 |- y- o1 T) Y
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。: i. S2 T: ~: A4 b* y% G( B
public virtual WalletAccount Import(X509Certificate2 cert), ^/ m5 b7 A/ T
        {
2 X! H3 z, n% T% ~# v            byte[] privateKey;+ G2 l7 [: M" q: g7 t% K
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())' a9 N' Q' l/ ^. L3 y
            {& p- K* X  }' ~$ c$ q) E
                privateKey = ecdsa.ExportParameters(true).D;
6 _) ]7 {/ O; N5 }4 T4 w" b( V3 r: F            }+ ~  ?& {9 }$ w+ @& B1 b
            WalletAccount account = CreateAccount(privateKey);
. _) ~0 W# ?5 L/ g7 r4 z7 A/ \            Array.Clear(privateKey, 0, privateKey.Length);& p9 _- c0 r: b$ v; f2 a. L
            return account;
: y2 j" b) S" d3 L* l        }/ V* }' s) }9 C. e- t4 n/ ?7 Z: F
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
6 O" e- w' X  Q4 a' O总结+ K  F4 p: e/ V: W! Q- u! w$ ^" D
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
, |. c2 V9 w% p参考资料
) O  \8 k! d4 @5 r$ y' K区块链技术指南
7 u+ ?! H5 b; X0 ^$ b0 r) g& LMurMurHash3, an ultra fast hash algorithm for C# / .NET
2 k4 s5 Q8 j3 W) l' H/ Lscrypt算法的前世今生(从零开始学区块链 192)/ A+ t- p9 A. z* f2 K# S
Wallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3