14天搞定Go语言,从0到1保姆级教程-Go语言密码学算法

学习了Go语言并发编程(14天搞定Go语言,从0到1保姆级教程-Go语言开发实战)。本篇将开始介绍Go语言密码学算法的学习。时至今日密码学已经发展了数千年,在公元前的古埃及就出现过使用特殊字符和简单替换形式的密码。近代密码的发展源自第一、二次世界大战对军事机密的保护。现代密码学的发展与计算机信息技术关系密切,已经发展为包括随机数、Hash 函数、加解密、身份认证等多个课题的庞大领域,相关成果为现代信息系统奠定了坚实的安全基础。

学习目标

(1)能够理解Hash的定义

(2)能够了解流行的Hash算法

(3)能够理解Hash与加密解密的区别

(4)能够掌握SHA—256

(5)能够理解对称加密简介

(6)能够掌握DES和3DES算法

(7)能够掌握AES算法和AES的加密模式

(8)能够掌握填充方式

Hash算法、对称加密算法

Ø Hash的定义

Hash (哈希或散列)算法是IT领域非常基础也非常重要的一类算法。可以将任意长度的二进制值(明文)映射为较短的固定长度的二进制值(Hash 值),并且不同的明文很难映射为相同的 Hash 值。Hash 值在应用中又被称为数字指纹(fingerprint)或数字摘要(digest)、消息摘要。

例如,计算hello blockchain的MD5 Hash值为“78e6a8bcdef7a4a254c16054b082c783”。这意味着只要对某文件进行 MD5 Hash 计算,得到结果为“78e6a8bcdef7a4a254c16054b082c783”,就说明文件内容很可能是 “hello blockchain”。可见,Hash 的核心思想类似于基于内容的编址或命名。

一个优秀的Hash算法,在给定明文和算法的情况下,可以基于有限时间和有限资源计算出Hash值。在给定(若干)Hash值的情况下,很难(基本不可能)在有限时间内逆推出明文。即使修改一点点原始输入信息,也能使Hash值产生巨大的改变。不同的输入信息几乎不可能产生相同的Hash值。

Ø 流行的Hash算法

目前常见的 Hash 算法包括Message Digest(MD)系列和Secure Hash Algorithm(SHA)系列算法。

MD 算法主要包括MD4和MD5 两个算法。MD4(RFC 1320)是 MIT 的 Ronald L. Rivest在 1990 年设计的,其输出为 128 位。MD4 已被证明不够安全。MD5(RFC 1321)是Rivest于 1991 年对MD4改进版本。它对输入仍以512位进行分组,其输出是128位。MD5比MD4更加安全,但过程更加复杂,计算速度要慢一点。MD5已于2004年被成功碰撞,其安全性已不足应用于商业场景。

SHA算法由美国国家标准与技术院(National Institute of Standards and Technology,NIST)征集制定。SHA-0算法于1993年问世,1998年即遭破解。随后的修订版本SHA-1算法在1995年面世,它的输出为长度160位的Hash值,安全性更好。SHA-1设计采用了MD4算法类似原理。SHA-1已于2005年被成功碰撞,意味着无法满足商用需求。为了提高安全性,NIST 后来制定出更安全的SHA-224、SHA-256、SHA-384和SHA-512算法(统称为SHA-2算法)。新一代的SHA-3算法也正在研究中。

目前MD5和SHA—1已经不够安全,推荐至少使用SHA-256算法。比特币系统中就是使用SHA-256算法。

SHA-3算法又名Keccak算法。Keccak的输出长度分别有:512位、384位、256位、224位。

SHA-3并不是要取代SHA-2,因为SHA-2目前并没有暴露明显的弱点。由于对MD5出现成功的破解,以及对SHA-1出现理论上破解的方法,NIST认为需要一个与之前算法不同的、可替换的加密杂凑算法,也就是现在的SHA-3。区块链中的以太坊系统就是使用Keccak256算法。

下面列举数字1经过Hash算法后形成的密文。

MD5(1),加密后长度为128位,16字节 。密文如下所示。

SHA1(1),加密后长度为160位,20字节。密文如下所示。

RIPEMD-160(1),加密后长度为160位,20字节。密文如下所示。

SHA256(1),加密后长度为256位,32字节。密文如下所示。

Keccak256(1),加密后长度为256位,32字节。密文如下所示。

Ø Hash与加密解密的区别

Hash是将目标文本转换成具有相同长度的、不可逆的杂凑字符串,而加密(Encrypt)是将目标文本转换成具有不同长度的、可逆的密文。如图所示。

选择Hash或加密的基本原则如下。

l 如果被保护数据仅仅用作比较验证,以后不需要还原成明文形式,则使用Hash。

l 如果被保护数据在以后需要被还原成明文,则需要加密。

对简单Hash的攻击,主要有寻找碰撞法和穷举法。

1. 寻找碰撞法

目前对于MD5和SHA1并不存在有效地寻找碰撞方法。

我国杰出的数学家王小云教授曾经在国际密码学会议上发布了对于MD5和SHA1的碰撞寻找改进算法,但这种方法和“破解”相去甚远。该理论目前仅具有数学上的意义,她将破解MD5的预期步骤降低了好几个数量级,但对于实际应用来说仍然是一个天文数字。

2. 穷举法(或暴力破解法)

通俗地说,就是在一个范围内,如从000000到999999,将其中所有值一个一个用哈希算法哈希,然后将结果和杂凑串比较,如果相同,则这个值就一定是源字串或源字串的一个碰撞,于是就可以用这个值非法登录了。

穷举法看似笨拙,但目前几乎所有的MD5破解机或MD5在线破解都是用这种穷举法。纠其缘由,就是相当一部分口令是非常简单的,如“123456”或“000000”。穷举法是否能成功很大程度上取决于口令的复杂性。因为穷举法扫描的区间往往是单字符集、规则的区间,或者由字典数据进行组合,因此,如果使用复杂的口令,例如“!@#$%^&*()”这种口令,穷举法就很难奏效了。

Ø SHA—256

SHA-256算法输入报文的最大长度不超过2^64 bit,产生的输出是一个256bit的报文摘要。SHA256算法步骤如下。

(1)附加填充比特。

对报文进行填充,使报文长度与448模512同余(长度=448 mod 512),填充的比特数范围是1 到512,填充比特串的最高位为1,其余位为0。就是先在报文后面加一个 1,再加很多个0,直到长度满足mod 512=448.为什么是448,因为448+64=512. 第二步会加上一个 64bit的原始报文的 长度信息。

(2)附加长度值。

将用64bit 表示的初始报文(填充前)的位长度附加在步骤1的结果后(低位字节优先)。

(3)初始化缓存。

使用一个256bit 的缓存来存放该散列函数的中间及最终结果。该缓存表示为A=0x6A09E667 , B=0xBB67AE85 , C=0x3C6EF372 , D=0xA54FF53A, E=0x510E527F , F=0x9B05688C , G=0x1F83D9AB , H=0x5BE0CD19 。

(4)处理512bit(16 个字)报文分组序列。

该算法使用了六种基本逻辑函数,由64 步迭代运算组成。每步都以256-bit 缓存值ABCDEFGH 为输入,然后更新缓存内容。

每步使用一个32bit 常数值Kt 和一个32bit Wt。

Ø 核心代码

下面列举一些基础工具函数,参见。

下面列举一些哈希函数的使用,如例所示。

下面列举一些哈希函数的使用,如例所示。

Ø 对称加密简介

对称加密(也叫私钥加密算法)指加密和解密使用相同密钥的加密算法。它要求发送方和接收方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信的安全性至关重要。

对称加密算法的优点是计算量小,加密速度快,加密效率高。

不足之处是,参与方需要提前持有密钥,一旦有人泄露则系统安全性被破坏;另外,如何在不安全通道中提前分发密钥也是个问题,密钥管理非常困难。

基于“对称密钥”的加密算法主要有DES、3DES(TripleDES)、AES、RC2、RC4、RC5和Blowfish等。本节将介绍最常用的对称加密算法DES、3DES(TripleDES)和AES。加密过程如图所示.

Ø DES和3DES算法

数据加密标准算法(Data Encryption Standard,DES)是加密和解密使用相同密钥的加密算法,也叫做单密钥算法或私钥加密算法,是传统密钥算法。它是IBM公司于1975年研究成功并公开发表的。

DES算法的入口参数有三个:Key、Data、Mode。

l Key是DES算法的工作密钥,8个字节共64位。

l Data是要被加密或被解密的数据。

l Mode为DES的工作方式,有两种:加密或解密。

在没有密钥的情况下,解密耗费时间非常长,基本上认为没有可能。加密解密耗时和需要加密的文本大小成正比,这是P问题。知道明文和对应的密文,求解所用的密钥,这是NP问题。目前还没有NP的求解算法,但是密匙很容易得到验证。想得到NP的解,只能暴力破解(穷举破解),攻击者使用自己的用户名和密码字典,逐一尝试登录。穷举验是对称加密仅有的求解方式,求解时间呈指数级增长。

DES算法把64位的明文输入块变为数据长度为64位的密文输出块,其中8位为奇偶校验位,另外56位作为密码的长度。首先,DES把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,并进行前后置换,最终由L0输出左32位,R0输出右32位。根据这个法则经过16次迭代运算后,得到L16、R16,将此作为输入,进行与初始置换相反的逆置换,即得到密文输出。DES算法具有极高的安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。56位长密钥的穷举空间为2^56,这意味着如果一台计算机的速度是每秒种检测100万个密钥,那么它搜索完全部密钥就需要将近2285年的时间,因此DES算法是一种很可靠的加密方法。3DES密钥是24字节,即192位二进制。

Ø AES算法

高级加密标准算法(Advanced Encryption Standard,AES)由美国国家标准与技术研究院(NIST)于2001年11月26日发布,并在2002年5月26日成为有效的标准。2006年,AES算法已然成为对称密钥加密中最流行的算法之一。该算法与其他对称密码算法相比更安全、效率更高。

AES使用128位、192位或者256位的密钥长度(密钥分别是16字节、24字节、32字节),使得它比密钥长度为56位的DES更健壮可靠。

264这个数大于全球小麦1000年的产量。如果1微秒验证1个密码(1秒验证100万个),穷举需要费时58万年。

1080 是当前人类可见宇宙中所有物质原子数目的总和。

Ø AES的加密模式

AES的加密模式对应中文名称如表所示。

加密模式(英文名称及简写)中文名称Electronic Code Book(ECB)电子密码本模式Cipher Block Chaining(CBC)密码分组链接模式Cipher Feedback Mode(CFB)加密反馈模式Output Feedback Mode(OFB)输出反馈模式

ECB:最基本的加密模式,也就是通常理解的加密,相同的明文将永远加密成相同的密文,无初始向量,容易受到密码本重放攻击,一般情况下很少用。

CBC:明文被加密前要与前面的密文进行异或运算后再加密,因此只要选择不同的初始向量,相同的密文加密后会形成不同的密文,这是目前应用最广泛的模式。CBC加密后的密文是上下文相关的,但明文的错误不会传递到后续分组,但如果一个分组丢失,后面的分组将全部作废(同步错误)。

CFB:类似于自同步序列密码,分组加密后,按8位分组将密文和明文进行移位异或后得到输出同时反馈回移位寄存器,优点最小可以按字节进行加解密,也可以是n位的,CFB也是上下文相关的,CFB模式下,明文的一个错误会影响后面的密文(错误扩散)。

OFB:将分组密码作为同步序列密码运行,和CFB相似,不过OFB用的是前一个n位密文输出分组反馈回移位寄存器,没有错误扩散问题。

Ø 填充方式

进行DES、3DES和AES三种对称加密算法时,常采用的是PKCS5Padding填充、Zeros填充(0填充)。

1. PKCS5Padding

每个填充的字节都记录了填充的总字节数。

“a”填充后结果为: [97 7 7 7 7 7 7 7]。

“ab”填充后结果为: [97 98 6 6 6 6 6 6]。

“一a”填充后结果为:[228 184 128 97 4 4 4 4]。

2. ZerosPadding

全部填充为0的字节。

“a”填充后结果为: [97 0 0 0 0 0 0 0]。

“ab”填充后结果为:[97 98 0 0 0 0 0 0]。

“一a”填充后结果为:[228 184 128 97 0 0 0 0]。

Ø 核心代码

DES的加密案例,参见。

3DES加密解密的案例,参见。

AES加密解密的案例,参见。

非对称加密算法、椭圆曲线加密算法和椭圆曲线数字签名算法、字符编码与解码

学习目标

(1)能够理解非对称加密算法

(2)能够掌握非对称加密算法实现数字签名

(3)能够理解椭圆曲线加密和数字签名的概念

(4)能够掌握Base64和Base58

Ø 非对称加密简介

非对称加密又叫做公开密钥加密(Public key cryptography)或公钥加密。指加密和解密使用不同密钥的加密算法。公钥加密需要两个密钥,一个是公开密钥,另一个是私有密钥;一个用于加密,另一个用于解密。

RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。其他常见的公钥加密算法有:ElGamal、背包算法、Rabin(RSA的特例)、椭圆曲线加密算法(Elliptic Curve Cryptography, ECC)。

非对称加密的缺点是加解密速度要远远慢于对称加密,在某些极端情况下,需要是时间甚至是对称加密的1000倍。非对称加密与对称加密的对比如表所示。

算法类型特点优势缺陷代表算法对称加密加解密密钥相同或可推算计算效率高,加密强度高需提前共享密钥;易泄露DES、3DES、AES、IDEA非对称加密加解密密钥不相关无需提前共享密钥,中间人攻击可能性低计算效率低RSA、ElGamal、椭圆曲线系列算法ECC

Ø 非对称加密算法实现数字签名

非对称加密不同于加密和解密都使用同一个密钥的对称加密,虽然两个密钥在数学上相关,但如果知道了其中一个,并不能凭此计算出另外一个。加密消息的密钥是不能解密消息的。因此两个密钥中,一个可以公开,称为公钥;不公开的密钥称为私钥,必须由用户自行严格秘密保管,绝不通过任何途径向任何人提供。

非对称加密算法分为两种:公钥加密、私钥解密和私钥加密、公钥解密。前者是普通的非对称算法的加密和解密,而后者被称为数字签名。目前主流的数字签名算法是椭圆曲线数字签名算法(ECDSA)。具体内容在下一节讲解。

总之,非对称加密算法中,公钥的作用是加密消息和验证签名,而私钥的作用是用来解密信息和进行数字签名。

Ø RSA算法

RSA算法基于一个十分简单的数论事实。将两个大素数相乘十分容易,想要对其乘积进行因式分解极其困难,因此可以将乘积公开作为加密密钥。密钥对的生成步骤如下。

(1) 随机选择两个不相等的质数p和q(比特币中P长度为512位二进制数值,Q长度为1024位)。

(2) 计算p和q的乘积N。

(3) 计算p-1和q-1的乘积φ(N)。

(4) 随机选个整数e,e与m要互质,且0<e<φ(N)。

(5) 计算e的模反元素d。

(6) 公钥是(N,e),私钥是(N,d)。

加解密步骤如下。

(1) 假设一个明文数m(0<=m<N)。

(2) 对明文m加密成密文c,算法如下所示。

(3) 对密文c解密成明文m,算法如下所示。

举例说明如下所示。

Ø 核心代码

生成RSA密钥文件,参见。

RSA加密与解密,参见。

Ø 椭圆曲线加密简介

椭圆曲线加密算法(Elliptic curve cryptography,ECC)是基于椭圆曲线数学理论实现的一种非对称加密算法。

椭圆曲线算法又细分为多种具体的算法。Go语言内置的是secp256R1算法。以太坊系统虽然也采用secp256K1算法,但是跟比特币系统的secp256K1算法上又有所差异。

椭圆曲线公钥系统是代替RSA的强有力的竞争者,与经典的RSA公钥密码体制相比,椭圆密码体制有明显的优势。

1、ECC与RSA算法的优势对比

(1)安全性能更高(ECC可以使用更短的密钥),同等安全强度下,两者秘钥长度的对比如图所示。

(2)处理速度快,计算量小,在私钥的处理速度上(解密和签名),ECC远比RSA快得多。

(3)存储空间占用小,ECC的密钥尺寸和系统参数与RSA相比要小得多,所以占用的存储空间小得多。

(4)带宽要求低使得ECC具有广泛的应用前景。

ECC的这些特点使它必将取代RSA,成为通用的公钥加密算法。

Ø 数字签名的概念

数字签名(Digital Signature)又称公开密钥数字签名、电子签章,是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。数字签名可以验证数据的来源,可以验证数据传输过程中是否被修改。

数字签名是通过非对称加密算法中的私钥加密、公钥解密过程来实现的。私钥加密就是私钥签名,公钥解密就是公钥验证签名。因此数字签名由两部分组成:第一部分是使用私钥为消息创建签名的算法,第二部分是允许任何人用公钥来验证签名的算法。数字签名的使用流程如图所示。

数字签名应该满足如下要求。

l 签名不可伪造。

l 签名不可抵赖。

l 签名的识别和应用相对容易,任何人都可以验证签名的有效性。

l 签名是不可复制,签名与原文是不可分割的整体。

l 签名消息不可篡改,任意比特数据被篡改,其签名便被随之改变,任何人都可以经验证而拒绝接受此签名。

Ø 核心代码

下面通过一个案例验证数字签名,参见。

下面通过一个案例验证数字签名,如例所示。

字符编码与解码

Ø Base64

Base64是一种基于64个可打印字符来表示二进制数据的方式。Base64使用了26个小写字母、26个大写字母、10个数字以及两个符号(例如“+”和“/”),用于在电子邮件这样的基于文本的媒介中传输二进制数据。Base64通常用于编码邮件中的附件。

Base64字符集如下所示。

Base64的编码过程如图所示。

步骤说明如下。

l 将每个字符转成ASCII编码(十进制)。

l 将十进制编码转成二进制编码。

l 将二进制编码按照6位一组进行平分。

l 将6位一组的二进制数高位补零,然后转成十进制数。

l 将十进制数作为索引,从Base64编码表中查找字符。

l 每3个字符的文本将编码为4个字符长度(3*8=4*6)若文本为3个字符,则正好编码为4个字符长度; 若文本为2个字符,则编码为3个字符,由于不足4个字符,则在尾部用一个“=”补齐;若文本为1个字符,则编码为2个字符,由于不足4个字符,则在尾部用两个“=”补齐,如图所示。

接下来通过一个案例演示Base64编码解码,如例所示。

Ø Base58

Base58是一种基于文本的二进制编码格式。这种编码格式不仅实现了数据压缩,保持了易读性,还具有错误诊断功能。Base58是Base64编码格式的子集,同样使用大小写字母和10个数字,但舍弃了一些容易错读和在特定字体中容易混淆的字符。Base58不含Base64中的0(数字0)、O(大写字母o)、l(小写字母L)、I(大写字母i),以及“+”和“/”两个字符。目的就是去除容易混淆的字符。简而言之,Base58就是由不包括(0,O,l,I)的大小写字母和数字组成。Base58字母表如下所示。

base58编码的整体步骤就是不断将数值对58取模,如果商大于58,则对商继续取模。以字符串”a” 为例。在ASCII码中,”a”的10进制为97,具体步骤如下。

l 97对58取模,余数为39,商为1。

l base58字符集中,索引下标39为g。

l base58字符集中,索引下标1为2。

l 得到结果为:g2。

l 反序列化后为:2g。

以字符串 “ab” 为例。”ab”转十六进制为6162,再转十进制为24930,具体步骤如下。

l 24930对58取模,余数为48,商为429。

l base58字符集中,索引下标48为q。

l 429对58取模,余数为23,商为7。

l base58字符集中,索引下标23为Q。

l base58字符集中,索引下标7为8。

l 得到结果为:qQ8。

l 反序列化后为:8Qq。

接下来通过一个案例演示Base58编码解码,如例所示。

Go语言密码学算法小结

主要总结了密码学的一些算法。通过阅读本章内容,相信读者已经掌握了Go语言加密解密的方法。完整的安全系统不仅仅需要具备这些算法,更需要安全的系统环境、物理环境。无论是系统的损坏还是人为的泄密,都非常容易造成安全问题。

    THE END
    喜欢就支持一下吧
    点赞8 分享
    评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容