Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

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

$ V" N; c8 F# n# C6 c+ ]; R5 {目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。
! X( V1 a1 A  {一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。% o. F1 f6 H' L1 \( _
也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。5 K- _: U0 M, ?- c0 k1 J% b& M
Neo中的hash算法* F1 d7 Y' m- x6 i
scrypt
8 B% F+ q5 ^( x5 I$ b4 Uscrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。& D6 L) r0 z+ c0 c
scrypt的参数7 o  [0 |8 A, ~9 r5 j) ~
https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors& ~& U, n$ i0 Q% `
Cpercival mentioned in his slides from 2009 something around
/ S. R) o8 n* r9 ^! P(N = 2^14, r = 8, p = 1) for
( B& p' z) U, J" B/ Fscrypt特点- |0 v1 [/ b2 |) H( J
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。3 r$ g6 M$ \" I5 `. R  B0 N4 k
Neo中如何使用scrypt
/ ]: ]4 [4 r5 y, q6 }2 l1 {// in NEP6Account0 o/ S: A& C6 Y5 s
   public NEP6Account(NEP6Wallet wallet, ( S4 b( r1 E$ ?5 [
              UInt160 scriptHash, KeyPair key, string password)
3 V) W9 Q1 ^& I: L            : this(wallet,
- u+ A6 d# l' `0 B: ~/ `              scriptHash,
3 U: m5 ^0 {! S! d              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))) @2 U1 R; z) Y+ ?
        {
$ t. K6 A. w) I( i+ S            this.key = key;! Z1 o5 V. _. Y9 x/ }: `( P
        }5 ~4 I6 U0 [+ Y, w- ?
// in class KeyPair7 F: ?4 f! r) X
public string Export(string passphrase, int N = 16384, int r = 8, int p = 8)
2 d- V2 f7 [) p& a{
2 m( D. h  V7 D6 ?- F# Q& d' o    using (Decrypt())4 j7 e- Q5 w- y) }% |
    {( p& l$ I5 k# d4 c/ O
        UInt160 script_hash = Contract.
9 A% e: r* l1 ]9 I$ H            CreateSignatureRedeemScript(PublicKey).ToScriptHash();
+ K5 m  d7 {9 q% G4 l1 m* m        ( ]5 c8 m8 T1 E5 q; v: t
        string address = Wallet.ToAddress(script_hash);- u( a' B# r2 D/ d, Z7 U
        byte[] addresshash = Encoding.ASCII.GetBytes(address)
" ], @+ B3 U* @! X7 K. Q            .Sha256().Sha256().Take(4).ToArray();
$ O" |7 M3 d+ g" M        + W, o0 R0 J! s8 d
        byte[] derivedkey = SCrypt.DeriveKey(
  B3 J. B+ B1 E8 k            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
3 r4 V0 k, p1 Z- n) Z        
7 ^$ z- v, {+ r) W2 @        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();$ G4 _, V# w; [  c- ~
        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();0 ^& v% X( e$ W8 H" n5 Q$ ~( a' F
        / j/ z( W* e) j7 m: \4 j9 |* y
        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)
0 T4 W% W4 s/ @5 T( w; j5 f. I            .AES256Encrypt(derivedhalf2);4 B! E/ i4 O/ Y0 a. q6 i* |6 U
        / w3 D+ M4 o& @7 y: Y" G6 e  E) I* i
        byte[] buffer = new byte[39];
3 X) B. U3 R; Q: [* ~        buffer[0] = 0x01;4 N) m8 v5 J+ C& ]
        buffer[1] = 0x42;
; T3 E9 h  O6 X        buffer[2] = 0xe0;# _. X  @3 T$ d, h- E& n
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
2 E7 d! M+ C- ^/ b! G) @( C        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
+ c) Y2 ~2 V& t9 w5 i$ Y        return buffer.Base58CheckEncode();( c4 Q8 M0 q2 h% m( r( n
    }
& w9 c7 F: S! x+ M0 ]% G* j}
8 I- ~9 B" r; S! s可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
( N4 ~+ `1 w- c( u, b, Q) @" h" xMurmur3
- |6 ]" d% J( c1 b4 u1 o7 SMurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]" I7 D2 C+ S2 j" U$ m5 w6 j
Murmur3特点
4 w* x5 R; G, _9 e1 `# `6 N1.碰撞率低
5 \6 H2 k" r! \4 u/ L4 E* e2.计算速度快
7 H  G9 f% n5 H5 d" B  D) R0 E3.擅长大文件的hash
$ ?- t) y. ?' zNeo中如何使用Murmur3
, V$ @; i2 e5 Y) s+ _! a0 A" m
2 O2 i6 {9 `: [- `6 B% K# XNeo中Murmur3; x- C7 {. A! x" |9 `5 k) e
Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
5 D$ ^# K# x9 XRIPEMD-1602 a# l, G, S' ?3 e
Neo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。
. u1 Y: A  r% i5 b' U( w8 n, p// in neo-compiler/neo/neo/Core/Helper.cs3 V4 o% @& Y& u2 w/ {
public static UInt160 ToScriptHash(this byte[] script)% x. {  H; o9 K; B% `. q
        {% M' |/ {& o8 L1 B6 B" N8 s! b3 F- V
            return new UInt160(Crypto.Default.Hash160(script));
8 {, ^/ }  f4 Y        }
% _' ]% b# d+ w& @- w6 CRIPEMD-160算法的特点
7 m$ g) r7 e9 T7 y5 qRIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):
, }- o, J9 |3 n7 Z8 M2 K6 Z$ X0 L: D; V加密算法体系
0 U3 }8 {6 d6 Q8 ?; s现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。. E5 c/ T- o1 }$ }7 U: I0 M1 W
加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。) o- Y: R7 Z) r! O3 b! o& p# {
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。' }( h! K5 a4 l. T) H  b
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
7 h; s& [+ a5 n% l* x3 a并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。$ s/ ^8 ?0 g- P' _$ K$ \& ?* v# p
对称加密
% H5 x/ y! A+ Q; Y# \8 d顾名思义,加解密的密钥是相同的。
1 Y2 W5 j  L; ?) w. @; |1 X对称加密优缺点) ]: |* Z/ Q- j
优点是加解密效率高(速度快,空间占用小),加密强度高。. Q+ m9 }' y6 |+ `7 v) I0 c
缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。
* ^" P, ]6 N" V8 z! ~适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。
! d* V7 a: M+ y0 q! N$ f对称加密实现/ }" D( m8 v( \$ q
对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。+ m* e9 s% D# Y9 E! t+ H( t
代表算法包括 DES、3DES、AES、IDEA 等。
$ p: g- U- W. C. E7 g0 D) sDES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
6 P6 L+ a: o8 R: j( {5 E3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
. s, m" g3 ?$ H- L% z$ |& }AES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。$ N/ l4 h! u; K) J! M
注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。; |; L# \! q+ y) N) J
Neo中的AES
5 P- P* T  N3 j, W% e, n- C在钱包的加解密中,使用了该算法。; Z! U  c4 \* f* y8 Q: \
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。' @! ?/ w! k9 u$ c# |
2 K0 M( `0 R4 K( {" B/ R
拿到私钥
. a1 ~* S8 r' I2 W, Y具体的过程,后面再仔细研究分享出来。
* \8 t, o: q, \6 I5 y  R$ c1 i非对称加密
0 z+ `5 f( |8 x6 D5 K4 X8 E, }( P- D非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。
8 q+ x9 f; _4 y+ S# S非对称加密优缺点
7 l$ s3 z; H, X; q9 D1.优点是公私钥分开,不安全通道也可使用。# A- N- o. j% f0 z
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。6 w1 s4 d3 i- U; B5 ~
非对称加密代表算法) z) n( j4 g! z1 Q& o, Y
非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。' S2 p7 c: _4 P% s3 k
代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
. g( l( p# K; F  z" R5 h4 c1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
* G( {  T' F5 Q+ M. l2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。
7 P; G: D/ U. ]7 ^+ Y3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。
! |# E7 u! L4 @5 z: L+ x( T# o4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。
1 P( I, H) b6 ~* S- |RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
/ M- N7 Z* `" h5 \, L- xNeo中的数字签名算法$ E9 W! v/ N  Z: \  _3 [+ n
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。8 d* y. `8 a  I$ u+ w
public virtual WalletAccount Import(X509Certificate2 cert)
4 f  O- _4 }" c( H1 l        {
+ p2 {5 a) N8 `) m% U  U            byte[] privateKey;
- ~# b' Z* x/ d            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
0 t" J0 H( G% ^            {
; S( E3 P8 B' b" f                privateKey = ecdsa.ExportParameters(true).D;2 u3 O1 @# L; A% o, u3 k8 \+ q
            }
* I( f4 @* h; R) V            WalletAccount account = CreateAccount(privateKey);
/ v0 p5 x5 w7 d! e) |1 i' H            Array.Clear(privateKey, 0, privateKey.Length);6 w" n3 s* I) _* W% T( A+ u; B! ?
            return account;
9 @# f* O6 `/ E5 j0 U        }' y5 p5 @8 r  F; k( V
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
; L$ D8 u. z; [3 U& a! L总结, ^9 N8 I# ^: Z+ S, k
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
' d$ d- h' [1 }* t! C# p参考资料
! g6 a) V- |/ e( \区块链技术指南! a) [- D8 ^+ ^9 }- a
MurMurHash3, an ultra fast hash algorithm for C# / .NET
; `' s0 v+ W* W, lscrypt算法的前世今生(从零开始学区块链 192)
# G# J% N8 L8 m7 rWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3