高深的密码学+复杂的区块链,其实也可以通俗易懂
- 童世红
密码学,在很多人看来是极为高深、只有数学家才能玩转的技术科学,不清楚如何才能应用于实际开发的过程中。本文将结合应用密码学比较深入的区块链,从扫盲、实战,再到实验、提高,一层层剥开密码学的“神秘面纱”。
扫盲班—密码算法解析
对称加密
用数学公示表示就是:
加密:Ek(P) = C
解密: Dk(C) = P
这里E表示加密算法,D表示解密算法,P表示明文, C表示密文。常见的对称加密方法有DES、3DES、Blowfish、RC2、AES以及国密的SM4。有同学会问,什么是国密啊?很机密么?没那么夸张,其实它的全称叫“国家商用密码”,是为了保障商用密码安全,国家商用密码管理办公室制定了一系列密码标准。
非对称加密
对称加密又快又方便,但是有个很大的坑——密码本容易被偷或被破解。从红军到二战,胜利的最大贡献其实就是破解密码。红军在数十倍的包围圈里面自由跳来跳去,那两台大功率电台功劳莫大。怎么能够防止这种情况呢?1977年三位数学家Rivest、Shamir 和 Adleman 设计了一种算法(所以叫RSA),把密钥分成两个,一个自己持有叫私钥(Private Key),另一个发给对方,还可以公开,叫公钥(Public Key),实现用公钥加密的数据只能用私钥解开:
加密: E公钥(P) = C解密: D私钥(C) = P
这下就不用再头痛如何把密码本给对方或被破解了,私钥由自己保管,敌方拦截到密文也没有办法。除了RSA之外,常见的非对称算法还有Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)以及国家商用密码SM2算法。非对称算法核心原理其实就是设计一个数学难题,使得用公钥和明文推导密文很容易,但是很难根据公钥、明文和密文推导私钥。RSA是基于大整数因式分解难度,也就是两个质数相乘很容易,但是找一个大数的质因子非常困难,理论上破解RSA-2048(2048-bit)的密钥可能需要耗费10亿年的时间。
这儿说点题外话:强烈不建议使用RSA,原因如下:
- 容易被破解:RSA-768可以在3个小时内破解,1024在理论上100小时内也可以破解。所以使用RSA,长度起步要2048。但是数学家彼得·舒尔研究了一个针对整数分解问题的量子算法 (舒尔算法),理论上破解2048的RSA在100秒之内(好在量子机还未投入使用)。
- 慢:密钥长度加到2048可以提升安全,但是计算过慢。
数字签名
不过通常不需要对发送信息的整个内容都加密,那样太慢。只需要计算一个信息的唯一信息摘要并对信息摘要加密解密即可,下面就会讲到数据摘要算法(俗称HASH算法),这也是数字签名的算法名称,很多时候是一个摘要算法+非对称算法,例如SHA1RSA, SHA256RSA等。
摘要算法
实战班—区块链应用
比特币之谁能动我的钱
index: 索引
value: 金额
hash:一个SHA256的数据摘要
script: 脚本,这个是重点要讲的
这个script是一串可执行的二进制代码,比特币定义了一个基于堆栈的脚本执行器,可以执行加减乘除、移位、HASH、验签等算法,类似于常见的科学计算器。当你想花费持有的比特币时,首先需要执行作为输入交易对应UTXO的脚本(script),称之为“解锁脚本”,只有执行成功才能继续。最常用的一个解锁脚本就是P2PKH脚本:

解锁时传入签名和公钥组成完整脚本:

翻译起来就是: “公钥的HASH160等于<脚本里面的值>并且用这个公钥对HASH值验证签名能够通过”。计算通过,才可以花费这笔资金。因为私钥保存在你自己手上,其他人无法计算出一个满足条件的签名,从而保证了这笔资金只有你自己可以使用。这里除了数字签名外,还有一点体现了中本聪真的很聪明,账本上不会存储你的公钥,而是其HASH160(双HASH,SHA256+RIPEMD160),由于HASH是单向的,从HASH无法反向推导公钥,这样大大减少未来量子机会带来的风险。
区块链-HASH链之如何防止篡改
这里就突出了HASH算法的特点:
- 数据改变一点点,HASH改变非常大。
- 无法给不同的数据计算出相同的HASH(或者说非常难)。
比特币和以太坊的公私钥—ECC算法
RSA又慢又不安全,所以比特币和以太坊都不采用,而是使用了更安全的椭圆曲线算法 – ECC来做非对称加密基础算法。ECC的210位算法难度就相当于RSA 2048的难度,性能则是数量级的区别。那么椭圆算法又是何方神圣呢?前面讲过非对称算法无非是设计一个数学难题,使得单向计算很方便,而反向计算很难,如RSA使用因式分解的原理,两个大质数相乘很容易,但大数分解质因子很难。
椭圆算法ECC其实就是利用乘法容易,而除法难的特点,设计一个乘法:K = k * G,其中大K是公钥,小k是私钥,G是生成点。由私钥推导公钥很容易,只需要k个G相加即可。但是从公钥推导私钥很难,也就是无法计算公钥K除以G。当然这个加法不能用我们日常的整数加减法,而是利用函数 所定义的一个特殊椭圆曲线上散列点的特性定义的加法。其中p是一个常数。不同p可以设计成不同的曲线,比特币使用的p = 2256 – 232 – 29 – 28 – 27 – 26 – 24 – 1,这个曲线的名称就叫secp256k1。这是一个非常大的数,曲线上的点是一个复杂散点,为了方便展示,这里用小很多的17阶曲线表示加法的定义:
- A + B +C = A + (B + C)
- A*(B+C) = A*B + A*C
- K = k * G, 大K是公钥,小k是私钥;
- 把明文编码成曲线上的点M;
- 生成一个随机数r;
- 计算密文C1=M + r*K, C2 = r*G,其中大K是公钥;
- 对方收到密文后,可以计算C1 - kC2 = M,其中小k是私钥;
- 攻击者得到C1、 C2,公钥K以及基点G,没有私钥是无法计算出M的。
实验班-如何使用算法
- 生成一个密钥(如果已经有密钥,这步也省了),如:

- 取一个加密器:
- 初始化成加密模式:
- 加密:
复习一下非对称加密和对称加密有什么区别啊?密钥分成公私钥对。所以和对称加密区别只是:
- 在生成密钥的时候是一对,叫KeyPair。
- 加密的时候用一个如公钥,解密用另一个。

其参数是HASH算法,如SHA-256, SM3, MD5等。调用update方法设置内容,然后调用digest就拿到HASH了。
数字签名

验签:
又比大象多一步。
内参必读
有几个要点在实际使用过程中必须要注意。
一、JDK自带的JCE实现算法不全
二、Android 使用Bouncy Castle注意
Bouncy Castle(BC)很强大,Google的android内核也集成了。但是,由于安全要求,这个加密包是阉割过的,自己再集成BC又导致包冲突。解决办法是换个包名,到https://rtyley.github.io/spongycastle/可以获取。
提高班-隐私保护
数字信封
- 准备一个生成器

- 添加接收人:
接收人可以是公钥证书、普通公钥或者密码,可以有多个。
- 制作信封
拆信封时,只要凭自己的公钥找到自己的收件人信息,然后用持有的私钥抽取内容即可。
- 所签署的合同使用公司的公钥可以验证确实是公司所签署;
- 能够进一步确定合同经办人的身份;
- 经办人如离职被吊销个人证书,不影响已有业务数据。
类似的原理可以应用到数字签名,实现:
- 群组签名:机构使用群组公钥做自己的公钥,可以通过验证签名确定签名属于指定的机构,而机构管理员可以进一步确定是那个成员签署的。
- 环签名:对于匿名要求,可以确定签名是来自于一个群组的成员,但是无法确定是具体哪个成员签署的。
- Paillier方案
- BGV和RLWE方案
- 基于其他数学难题的方案

友情链接
联系我们

恒 生 技 术 之 眼