Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
429 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。
" ?, u( y0 a; Y3 V8 j. Q关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。
$ e. z: t  s$ n2 U& L0 A; i; ?Hash 算法
7 W4 O- s5 q1 \2 \" FHash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。
. q3 ^# b2 y- h- R4 ~  Z
2 e1 a2 `' |2 `# `4 Q) X& v* Z注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
& `; e4 N* t  N# ]2 ?3 L- Q: O0 u哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
' t5 i7 `5 M- y1 |3 j! I7 \一个优秀的 hash 算法,将能实现:
# Q" v8 t! \4 H" u4 \正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。
0 R5 }: g3 r6 I. z  L
% n( l. H# C4 k' F; S) ~6 B
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。/ d6 f6 \" @% u( v* K, a  p  S% z
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
! m8 A7 x8 K2 z, \! j" ^也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。; |* v! O) _7 @% G" N% P
Neo中的hash算法
3 y$ F! ~2 a, M. C2 A; N" V& sscrypt% W) z$ k9 |# M7 k4 }$ N4 [2 m' |
scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。6 {7 L+ E1 e- B+ j
scrypt的参数- e3 E- P& B& D" p4 {; f- J
https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors% C! B7 I4 @2 J7 X8 ?* M) y) ^
Cpercival mentioned in his slides from 2009 something around
9 r3 a& t; G, ]/ W* e4 P(N = 2^14, r = 8, p = 1) for
7 E. Z7 j9 H8 {scrypt特点! m- j9 H+ E) T  G0 t- }( e
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。
, \0 Q- ]* m/ g/ A0 `, D# SNeo中如何使用scrypt
8 h2 c) X  S0 c. G2 q$ ?3 w// in NEP6Account$ V; |' f  S$ g9 L4 }: y- M6 d
   public NEP6Account(NEP6Wallet wallet, + l' n; ?$ Z! n
              UInt160 scriptHash, KeyPair key, string password)
( O3 n1 s# y6 U            : this(wallet,
0 W: p1 Q1 l! y              scriptHash,
. n% |6 p5 E  k, X9 R( I3 u              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
) w% e9 k; b5 G2 a. W: o: f        {& d# L* ^4 {6 v" o0 M
            this.key = key;+ s' L4 z) D. T& L$ C) N
        }0 z4 T$ r5 Q. v) w8 c6 t8 T* _0 h
// in class KeyPair
" y" K1 v( X2 rpublic string Export(string passphrase, int N = 16384, int r = 8, int p = 8)' U+ r  c6 t4 t9 h% q+ M! N
{
# w- W2 I  d( `7 D  Q+ w    using (Decrypt())
% X) v$ Z4 d9 {3 A2 c    {
$ r( `8 C/ t. ~5 A1 u        UInt160 script_hash = Contract.! u6 ]$ i! u" N& Z: W9 A1 u
            CreateSignatureRedeemScript(PublicKey).ToScriptHash();- c; g, H9 r9 V
        
7 n8 ]# y3 _& M9 `/ Y        string address = Wallet.ToAddress(script_hash);7 Z8 [' {! x* Y
        byte[] addresshash = Encoding.ASCII.GetBytes(address)
- ^. Y/ `. Z' Q            .Sha256().Sha256().Take(4).ToArray();; h& z( e; c2 O5 O3 m  s; o
        3 X. x% j2 T* u% n8 x" t' @7 v
        byte[] derivedkey = SCrypt.DeriveKey(/ v" s+ P+ ?) M% ~& t6 A
            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
8 e8 O% R# s) T  C; m        
  R7 p1 X) A/ E+ O. E        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();/ M( q. G8 Q6 E  b6 g3 ]
        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
! t. n: i" O. I8 @# ]8 s        
4 X$ j/ f3 J# X7 e        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)  l; ^; [) o  K9 P: |* S# i
            .AES256Encrypt(derivedhalf2);) W7 q1 P; G+ s0 g
        : B4 l" O. r  S" q
        byte[] buffer = new byte[39];5 }+ o/ e  _7 R$ P7 X7 [
        buffer[0] = 0x01;
- c/ S, N! r. b- \        buffer[1] = 0x42;; A, p; [' k3 Z' w$ ~8 O* D
        buffer[2] = 0xe0;
4 n$ ?9 O) H! i% O: V+ P        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
/ q( m* {4 @# _- h* O/ h0 M# @8 n        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
4 ?4 G- {, Q) r: g        return buffer.Base58CheckEncode();
* H8 ~1 m1 T) I: W) a    }
+ `& A8 p) D6 y6 u2 k0 ~7 u}# G2 @4 O2 p- e$ }$ M' u/ y
可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。2 ^( S8 X  y  T8 X# a* W3 W
Murmur3
! A3 ]7 h9 P$ g# s/ O" D! ^MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]
* T0 d2 v8 Y2 O. u' k4 Q. [- RMurmur3特点" a' S$ g: H4 i" C3 X4 G
1.碰撞率低" S7 d, B, [* D# m. N1 T  k
2.计算速度快
- P' O5 ?2 s! K+ E) X( c% k! {, j3.擅长大文件的hash
4 t" J) W% O. y+ ~' [7 w* LNeo中如何使用Murmur3
- b# t" w! [( z4 z1 a' ~, v4 ?( z* o  v* g+ M* ~) e) ~
Neo中Murmur3/ O( A; X; W) o9 A( K* A3 Y
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。3 a! x) _* J0 E) @1 `
RIPEMD-160
0 V! r; c# T- |' o' v. I/ HNeo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
; c; T- G& t) N# ?% [) u// in neo-compiler/neo/neo/Core/Helper.cs. X) u3 T! x, c0 n5 N, g6 j9 x; x
public static UInt160 ToScriptHash(this byte[] script)
! N3 ~  @3 @1 {8 |7 i0 W1 J        {
/ z) h/ O" @5 w7 W& o/ K8 O0 r0 e            return new UInt160(Crypto.Default.Hash160(script));; B" y- F2 w  f  o! M/ h) u" \
        }
4 s* m8 C% T, F3 i( j) ]4 o2 F/ SRIPEMD-160算法的特点4 @6 t/ x  u# \( s
RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
8 `) I4 ]' _6 x" E4 g8 Q加密算法体系4 O/ W+ _1 P1 W4 B# q1 L
现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。
( k$ b8 s" g+ [1 e) N2 l- n- @加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。% _% V5 q  R1 u; \5 Z' f
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。6 c1 F" z8 X# Q
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
& e# l& o# t  y% E; z. |5 B并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。
& g* J: k/ U8 S; ?, I- q- F对称加密
4 n9 C! s; L  T# }# U' J  }顾名思义,加解密的密钥是相同的。, L% A% }: O+ d+ D
对称加密优缺点
1 v7 Q1 s" O7 Z6 j优点是加解密效率高(速度快,空间占用小),加密强度高。
. Q* K* |' l4 C( d) }+ e" w4 ]缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。
) f2 L. R' F; }# v, r+ F4 Q适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
! l( ^+ l2 n( |9 G, u对称加密实现
; J0 K" K$ r6 {6 \% M对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。
$ y3 t7 C& x/ t& c* X代表算法包括 DES、3DES、AES、IDEA 等。
$ ~# J$ k, n9 S2 J2 @8 U/ EDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
/ O0 o& y# R7 q3 I; n( y) B3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。0 o4 ^# \1 f" @
AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
2 i) G' j" [9 ~2 f2 S" H9 ~注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
" S' a* _( L) l5 }; A- YNeo中的AES
+ |' _0 q& w5 Q, B; \# q& z3 |在钱包的加解密中,使用了该算法。
6 w# G- {/ l) P下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
/ j* j, H" l  L4 ], I+ Z( D
0 e* d8 M) Z% b! J拿到私钥
! m& v$ H9 [6 J9 w具体的过程,后面再仔细研究分享出来。
5 u* k1 H0 l. @- a9 L% D非对称加密4 L1 V8 Z2 H) N- g& h
非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。* A  E; [/ k! Z. j0 g
非对称加密优缺点4 X5 z% L4 ?: N8 e! ?
1.优点是公私钥分开,不安全通道也可使用。# b8 w2 v: @3 Q5 Y* m
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。! s4 A2 _' W$ L; i
非对称加密代表算法
9 b# h; {( j+ D/ g/ V2 R非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
+ }4 N9 f2 Z) R% s: A代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。7 \: y' a: h$ u: I
1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
0 N. Q# N& ~4 _( m+ u9 K2 q$ A2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。
! e" r2 D2 a/ M/ x' `  E$ F, J3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
' W' b3 p5 y, y/ y* Y- S4 r4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。6 `" k. a5 d5 ~" i
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。% J. V' ]3 E% N# t3 h5 j7 t
Neo中的数字签名算法$ t$ i) W% J) P7 p% m6 |& S
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。' H1 W, x5 u. t7 W2 X/ K8 j- U
public virtual WalletAccount Import(X509Certificate2 cert)
- {4 |; k, b- M' p+ d; V- b        {4 c; H3 _' [+ P: {" |2 u: l% ^" R
            byte[] privateKey;1 C: W7 \3 G7 n
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
  [9 m9 j/ K8 W7 z- ^! r% H! a            {
0 @8 m. F# D1 r& Z  b1 A: q                privateKey = ecdsa.ExportParameters(true).D;
! l0 {! {0 ]& z$ r% I            }
& H  E0 m3 V* E- O. Q            WalletAccount account = CreateAccount(privateKey);
9 Y- |* D% q0 M) T: X) Z3 m1 e            Array.Clear(privateKey, 0, privateKey.Length);7 X: D2 U$ v' [
            return account;
- w; x; |7 j7 \: D/ r        }' n4 U) Z6 @2 m
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。( B* G, \4 U. y, D4 p2 e; C
总结0 H7 @4 I6 J" |9 @* g# A
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
% q/ I% g9 M% M6 L. W1 `" G- S参考资料; m. }. B2 ^- O2 w, X# p( \
区块链技术指南. o! q8 g( f1 Z/ F7 u, F
MurMurHash3, an ultra fast hash algorithm for C# / .NET5 v  T6 r  \- e8 E
scrypt算法的前世今生(从零开始学区块链 192)8 t$ h& I$ z1 H
Wallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3