Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

空港训港j
364 0 0
区块链是基于加密算法,共识算法,p2p网络和经济激励的一个系统,加密算法在里面起到了非常关键的作用,总结一下Neo使用到的加密算法吧。: @: A! @: `7 ^, W3 ?; o
关于区块链中密码学的介绍,yeasy大牛的文章已经介绍的非常好,下文主要通过和Neo结合,加上一些自己的理解,去讲述一下加密算法的使用方法。* {; M0 u: t1 z' m, }" K! j+ ~1 w9 w
Hash 算法
! O4 ?; E* v3 \9 D9 }* o0 \Hash (哈希或散列)算法是信息技术领域非常基础也非常重要的技术。它能任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。4 }- m& U3 H. w) c1 R: }$ a9 N. }) J% ]
( |; L! U0 e4 s8 Z  F( f
注意上一篇文章说明了如何将hash后的字符串保存到Neo的UInt256类型,其中一个前提就是结果集合在[0-15]之间。
# R4 ^: z; n0 P) Y6 b$ ]7 T) C哈希完全不等于加密,很多时候开发人员都对用户表中的密码进行哈希后保存,实际上不叫做加密,只是相当于把密码的“特征指纹”保存下来,而对非法攻击者来说,在不知道真实的“密码”的情况下,得到有相同指纹的密码是极为困难的。
0 P. k, z' A& U! u一个优秀的 hash 算法,将能实现:6 n: c8 ?4 N# |1 ~- ^
正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。# Q) G; E2 L7 g$ c
9 `+ F( ]# y; v, D
目前,一般认为 MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。. b* A( M) C" y- Y1 C/ t
一般的,Hash 算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的 CPU 进行 Hash 的速度也越快。
0 z+ F7 v/ M! y& d8 E  {) P5 |也有一些 Hash 算法不是算力敏感的,例如 scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。
$ {7 i2 B6 @- l7 sNeo中的hash算法7 P3 S( i* d& f/ e# `1 o. F
scrypt
0 v( i. w3 O" X- ^! Rscrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用,并且缺乏仔细的审察和广泛的函数库支持。所以scrpyt一直没有推广开,但是由于其内存依赖的设计特别符合当时对抗专业矿机的设计,成为数字货币算法发展的一个主要应用方向。
, {0 N4 P, f. a' e6 c% pscrypt的参数7 I  O1 \1 z6 p- p9 W: F; `5 u
https://stackoverflow.com/questions/11126315/what-are-optimal-scrypt-work-factors
; f( W% X7 Y, u. q% U+ fCpercival mentioned in his slides from 2009 something around# p! q7 g8 y. ?8 L% ]3 N5 C
(N = 2^14, r = 8, p = 1) for 4 o7 }* t1 g* r  c% u
scrypt特点# v! k; U" y% `/ W; E
scrpyt的出名主要是因为莱特币为了抵抗比特币矿机采用的一个算法,可以指定内存和cpu的使用量,可以用参数确定hash的时间。+ Z0 T$ p3 c8 d% `( ?
Neo中如何使用scrypt3 ]# c/ D5 Y8 r6 Q! Y# G( u
// in NEP6Account
( G5 ^8 m9 g- ?; J   public NEP6Account(NEP6Wallet wallet, - Z- Q. v9 T. H
              UInt160 scriptHash, KeyPair key, string password)( K' r( z! h" O& c5 q2 [( p( b3 j
            : this(wallet, ) ?( \2 a! R1 _; q! P! ^
              scriptHash, 6 `" r1 c5 O. r) p2 C
              key.Export(password, wallet.Scrypt.N, wallet.Scrypt.R, wallet.Scrypt.P))
5 d! E0 z' H* {. |1 |. R& c! N6 d        {
6 e9 o  M( U- R" r% P+ m6 l7 x            this.key = key;- |5 s- P2 E1 t; a2 l* I" w
        }
8 l: n# m1 O9 p  `. U. P* P2 h* V// in class KeyPair
7 c: R+ L% N" z; C" lpublic string Export(string passphrase, int N = 16384, int r = 8, int p = 8)9 \" P' z- g& c
{; d/ [5 p3 b9 V; _4 ?4 X4 {2 G
    using (Decrypt())
! S: `, C' J7 ]' n. o' \    {) G) N' L  W9 @% T6 \& U( f
        UInt160 script_hash = Contract.
" }& n, N6 k3 q            CreateSignatureRedeemScript(PublicKey).ToScriptHash();0 n7 _6 q0 P# q1 k4 O
        
. H* S7 `3 o9 M3 g5 S% c: \6 t        string address = Wallet.ToAddress(script_hash);
, |4 G! H- Q4 t7 Z8 x        byte[] addresshash = Encoding.ASCII.GetBytes(address)
7 @/ x7 r! I! G3 d            .Sha256().Sha256().Take(4).ToArray();8 N; M% l* J7 Y0 @
        : S% F& l- x. c; ]: [
        byte[] derivedkey = SCrypt.DeriveKey(
' Y4 v6 Q, ]# O5 [6 ~9 h            Encoding.UTF8.GetBytes(passphrase), addresshash, N, r, p, 64);
5 ]6 \0 S4 Q' y( Z7 g8 k2 R        0 ~5 K2 h* ]4 A, Y9 r# o" Z
        byte[] derivedhalf1 = derivedkey.Take(32).ToArray();) ?$ L3 A9 W4 p- `4 Q$ h
        byte[] derivedhalf2 = derivedkey.Skip(32).ToArray();
8 N, i% i# E) j) F+ ^        
4 |! N0 C/ u, P; j' v" e: C        byte[] encryptedkey = XOR(PrivateKey, derivedhalf1)& k6 O8 `$ f( w5 F+ t
            .AES256Encrypt(derivedhalf2);/ F0 i1 R) W% L+ [; Y  d. M
        ( Q. |, Q; p. F: Z0 F* u7 q: W
        byte[] buffer = new byte[39];
: }3 @7 X  N! l        buffer[0] = 0x01;
, v' a$ n6 i' |5 p        buffer[1] = 0x42;, G7 o) ?5 r6 \4 k: s6 |  c. D
        buffer[2] = 0xe0;# {1 d& Z! T) ]
        Buffer.BlockCopy(addresshash, 0, buffer, 3, addresshash.Length);
% h" Z2 E& N, C! S: d0 v8 w        Buffer.BlockCopy(encryptedkey, 0, buffer, 7, encryptedkey.Length);
8 E6 A  {. @2 g/ D# w8 N        return buffer.Base58CheckEncode();- i* d% T: y& s1 X3 e: p  S# b
    }' t7 d8 Y$ \4 a1 ?0 @) d
}
* O6 p0 I5 p4 L' Y  Z6 p+ w3 ~" n可见SCrypt.DeriveKey方法参与了加密密钥的生成过程。后面解密也必然使用到了这个hash算法。所以该hash算法参与了加密过程,而加密密钥用AES256Encrypt生成。可以确定的是,使用该算法的逆过程,可以解密出密钥来,这个比WIF要安全。
: v% F% X  x2 o0 }- i; z; b2 AMurmur38 _4 s6 N* o( h3 U0 u2 t
MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。[1][2][3]由Austin Appleby在2008年发明,[4][5] 并出现了多个变种,[6] 都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。[7]  L+ d6 A% P* @$ j0 t- I' [9 I
Murmur3特点
) S! f9 M6 J, G( K; P1.碰撞率低; N- c5 h. M* f: b9 t) M# c2 j2 q3 d
2.计算速度快  q) f3 p8 y: y! [% g3 w; L4 j
3.擅长大文件的hash
: R3 _( S# Q. V; _: ?" }Neo中如何使用Murmur3
) Y/ W/ D& b7 ?0 S% O; F1 ~& q
5 y1 P3 Y  t8 ?& _Neo中Murmur3
6 j% l' c3 j- y- u' f5 ]Murmur3的具体算法,以后再研究,现在大致知道,Neo用Murmur3生成key,也在BloomFilter中使用了。
9 e+ k; ~/ a# M; i4 n; P" Y) dRIPEMD-160
- I- [6 s% e/ Y+ b  p6 n8 E8 `Neo中用这个算法来生成短一点的hash值,script hash就是用了这个算法。! K6 {" D5 S3 n# y: z- {% _8 X
// in neo-compiler/neo/neo/Core/Helper.cs
5 }! T/ Q7 I3 L6 ^4 Z3 A public static UInt160 ToScriptHash(this byte[] script)! ^# B% O8 y8 [' s, b
        {3 N' e' P3 n1 N( t0 Q; U
            return new UInt160(Crypto.Default.Hash160(script));
% ]. o9 Z6 X0 x! U6 @  k        }% q/ O) W! [5 e) ]+ Y7 }2 J4 ~( J
RIPEMD-160算法的特点! L* v4 T% s& r/ K
RIPEMD-160能表现出理想的 雪崩效应 (例如将 d 改成 c,即微小的变化就能产生一个完全不同的哈希值):- ~# n/ r& R- Z+ Z  F& }
加密算法体系
: ~) F2 ~- M9 ~" x" H9 Z现代加密算法的典型组件包括:加解密算法、加密密钥、解密密钥。其中,加解密算法自身是固定不变的,一般是公开可见的;密钥则往往每次不同,并且需要保护起来,一般来说,对同一种算法,密钥长度越长,则加密强度越大。: t% {/ }% S9 X1 ~0 v: l! Y- D
加密过程中,通过加密算法和加密密钥,对明文进行加密,获得密文。) h5 [1 c3 }5 s9 _) t2 E( i8 e0 R
解密过程中,通过解密算法和解密密钥,对密文进行解密,获得明文。# L" S; M1 }; d- {
根据加解密的密钥是否相同,算法可以分为对称加密(symmetric cryptography,又称公共密钥加密,common-key cryptography)和非对称加密(asymmetric cryptography,又称公钥加密,public-key cryptography)。两种模式适用于不同的需求,恰好形成互补,很多时候也可以组合使用,形成混合加密机制。
4 p! H5 G/ q3 t2 I! Z0 C" j并非所有加密算法的强度都可以从数学上进行证明。公认的高强度加密算法是在经过长时间各方面实践论证后,被大家所认可,不代表其不存在漏洞。但任何时候,自行发明加密算法都是一种不太明智的行为。
1 m% h$ K- v6 b1 S/ U对称加密
1 K6 X. C7 J" `0 A0 `顾名思义,加解密的密钥是相同的。
, F3 A' B$ Z% {" N" F. n对称加密优缺点, V$ r( ~9 y& K  F9 n
优点是加解密效率高(速度快,空间占用小),加密强度高。7 U, G1 Z' v" V
缺点是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。6 i# w, V9 ~, X% G* E8 }
适用于大量数据的加解密;不能用于签名场景;需要提前分发密钥。' O, R9 S* L. N
对称加密实现
& @1 l. R2 l$ G1 U' h对称密码从实现原理上可以分为两种:分组密码和序列密码。前者将明文切分为定长数据块作为加密单位,应用最为广泛。后者则只对一个字节进行加密,且密码不断变化,只用在一些特定领域,如数字媒介的加密等。$ c. F- w$ s6 l) H  Y; u
代表算法包括 DES、3DES、AES、IDEA 等。- l$ ]9 a6 ?! s7 Z
DES(Data Encryption Standard):经典的分组加密算法,1977 年由美国联邦信息处理标准(FIPS)所采用 FIPS-46-3,将 64 位明文加密为 64 位的密文,其密钥长度为 56 位 + 8 位校验。现在已经很容易被暴力破解。
+ M. G( K4 \% N& q  `$ p. b# T0 C3DES:三重 DES 操作:加密 –> 解密 –> 加密,处理过程和加密强度优于 DES,但现在也被认为不够安全。
1 T, w2 \2 h+ H( d# N6 dAES(Advanced Encryption Standard):美国国家标准研究所(NIST)采用取代 DES 成为对称加密实现的标准,1997~2000 年 NIST 从 15 个候选算法中评选 Rijndael 算法(由比利时密码学家 Joan Daemon 和 Vincent Rijmen 发明)作为 AES,标准为 FIPS-197。AES 也是分组算法,分组长度为 128、192、256 位三种。AES 的优势在于处理速度快,整个过程可以数学化描述,目前尚未有有效的破解手段。
0 q: s$ t- ]  M5 S- s; j' b注:分组加密每次只能处理固定长度的明文,因此过长的内容需要采用一定模式进行加密,《实用密码学》中推荐使用 密文分组链接(Cipher Block Chain,CBC)、计数器(Counter,CTR)模式。
5 a* d+ b; _- `; f$ O. \& BNeo中的AES
: v" s0 K( ?4 }9 b+ F在钱包的加解密中,使用了该算法。) P0 C/ p3 Y% J! F" }/ F4 m
下图的代码在/neo/Wallets/Wallet.cs中,NEP是neo enhancement proposal的意思。参数nep2就是符合这个格式的一个Neo钱包文件。
. R0 W7 x& ?) w( J) F! s
5 k7 l, @. T5 d! ?拿到私钥2 Z& w, `3 m" H" W' v
具体的过程,后面再仔细研究分享出来。
: {- g) A$ ?. O$ `: d" V9 [非对称加密
- o- m7 w5 ~# B  Z' G/ b非对称加密是现代密码学历史上最为伟大的发明,可以很好的解决对称加密需要的提前分发密钥问题。顾名思义,加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。
* E% B  x* T/ L非对称加密优缺点" B9 {  T6 U3 G% ~7 {
1.优点是公私钥分开,不安全通道也可使用。( I; m2 ]9 B, j% h. i
2.缺点是加解密速度慢,一般比对称加解密算法慢两到三个数量级;同时加密强度相比对称加密要差。
  I3 R! ?% ]  Q3 z非对称加密代表算法
7 b/ L2 \1 F, ?+ W+ e  Y$ ?% E非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。
% m+ p, ?" O" b! A& E) [代表算法包括:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。
: s9 C/ D6 f" s+ j) T1.RSA:经典的公钥算法,1978 年由 Ron Rivest、Adi Shamir、Leonard Adleman 共同提出,三人于 2002 年获得图灵奖。算法利用了对大数进行质因子分解困难的特性,但目前还没有数学证明两者难度等价,或许存在未知算法在不进行大数分解的前提下解密。
7 n" U& v3 e" U7 @% S7 L% p! I2.Diffie-Hellman 密钥交换:基于离散对数无法快速求解,可以在不安全的通道上,双方协商一个公共密钥。% A% m: K  T6 H" M
3.ElGamal:由 Taher ElGamal 设计,利用了模运算下求离散对数困难的特性。被应用在 PGP 等安全工具中。' W- z  E# g8 Q
4.椭圆曲线算法(Elliptic curve cryptography,ECC):现代备受关注的算法系列,基于对椭圆曲线上特定点进行特殊乘法逆运算难以计算的特性。最早在 1985 年由 Neal Koblitz 和 Victor Miller 分别独立提出。ECC 系列算法一般被认为具备较高的安全性,但加解密计算过程往往比较费时。一般适用于签名场景或密钥协商,不适于大量数据的加解密。' {6 G6 Q, b9 h9 f7 W* L
RSA 算法等已被认为不够安全,一般推荐采用椭圆曲线系列算法。
# Y$ W# x3 }  c$ {3 C0 u9 rNeo中的数字签名算法+ _- n5 k2 {( |$ H( Y2 Q% [. b: N
在Neo中,也使用了非对称加密算法,我们通过代码来看看是如何使用的。
( ^, x' ~' m& m7 opublic virtual WalletAccount Import(X509Certificate2 cert)" h' E2 @% Q7 {* p
        {
. [- P% W! Y. j! d3 u( Y5 Y: U            byte[] privateKey;! r' c" d$ }) K  H; }
            using (ECDsa ecdsa = cert.GetECDsaPrivateKey())2 l# r0 o1 Z. \  F
            {
" c6 p% E! m2 o+ }9 [                privateKey = ecdsa.ExportParameters(true).D;
$ b" ^$ H% S; x0 p) T" m- s            }4 ^) Q! @) G  B; T3 |9 \
            WalletAccount account = CreateAccount(privateKey);2 _, s: w2 [7 b) D# f( c
            Array.Clear(privateKey, 0, privateKey.Length);* |6 T0 r" y! k, Y2 r8 U
            return account;% D5 v0 E# d2 }* {. @" G. L
        }# ~' C. X7 m# o3 U) p/ C
X509Certificate2是数字证书,和我们在https里面使用的是一样的,从里面拿出私钥后,创建钱包。
  b& @9 {2 m9 J. q) p) t0 G" [! k/ P总结( J; C' ]1 A; o" Z1 Z6 V
目前只是简单的介绍了一下Neo中加密算法的使用情况,这些加密算法的原理和实现也是很有意思的,后面看看怎么实现的,再分享出来。
7 r) p$ P8 U5 K( X" c+ ?$ c8 ?$ C参考资料
$ U. S  \2 Q* J: Q区块链技术指南
; r/ {6 G% w1 [3 ]6 @+ n# MMurMurHash3, an ultra fast hash algorithm for C# / .NET
8 L; L7 C# N2 Q' B! V# C1 @scrypt算法的前世今生(从零开始学区块链 192)
8 h# c6 L( K7 d6 X. B& ]2 XWallet import format
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

空港训港j 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    3