(转)Go加密算法总结
原文:https://www.cnblogs.com/you-men/p/14160439.html
加密解密在实际开发中应用比较广泛,常用加解密分为:“对称式”、“非对称式”和”数字签名“。
对称式:对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。具体算法主要有DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法。
非对称加密(公钥加密):指加密和解密使用不同密钥的加密算法,也称为公私钥加密。具体算法主要有RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)。
数字签名:数字签名是非对称密钥加密技术与数字摘要技术的应用。如MD5、SHA1、HMAC等, 主要用于验证,防止信息被修改, 如:文件校验、数字签名、鉴权协议;
以下介绍golang语言主要的加密解密算法实现。
2|0md5
MD5信息摘要算法是一种被广泛使用的密码散列函数,可以产生出一个128位(16进制,32个字符)的散列值(hash value),用于确保信息传输完整一致。
3|0hmac
HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,
它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中。
和我们自定义的加salt算法不同,Hmac算法针对所有哈希算法都通用,无论是MD5还是SHA-1。采用Hmac替代我们自己的salt算法,可以使程序算法更标准化,也更安全。
4|0Base64
4|1base64不是加密算法
它是一种数据编码方式,虽然是可逆的,但是它的编码方式是公开的,无所谓加密。本文也对Base64编码方式做了简要介绍。
4|2实现Base64编码解码
Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。 首先使用Base64编码需要一个含有64个字符的表,这个表由大小写字母、数字、+和/组成。采用Base64编码处理数据时,会把每三个字节共24位作为一个处理单元,再分为四组,每组6位,查表后获得相应的字符即编码后的字符串。编码后的字符串长32位,这样,经Base64编码后,原字符串增长1/3。如果要编码的数据不是3的倍数,最后会剩下一到两个字节,Base64编码中会采用\x00在处理单元后补全,编码后的字符串最后会加上一到两个 = 表示补了几个字节。
5|0sha1
6|0bcrypt加密
7|0AES
密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。AES中常见的有三种解决方案,分别为AES-128、AES-192和AES-256。如果采用真正的128位加密技术甚至256位加密技术,蛮力攻击要取得成功需要耗费相当长的时间。
AES有五种加密模式
7|1ECB模式
出于安全考虑,golang默认并不支持ECB模式。
7|2CBC模式
7|3CRT模式
7|4CFB模式
7|5OFB模式
7|6RSA加密简介
7|7rsa加密算法简史
RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
7|8rsa加密算法实现原理
学过算法的朋友都知道,计算机中的算法其实就是数学运算。所以,再讲解RSA加密算法之前,有必要了解一下一些必备的数学知识。我们就从数学知识开始讲解。
7|9必备数学知识
RSA加密算法中,只用到素数、互质数、指数运算、模运算等几个简单的数学知识。所以,我们也需要了解这几个概念即可
7|10素数
素数又称质数,指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数。这个概念,我们在上初中,甚至小学的时候都学过了,这里就不再过多解释了。
7|11互质数
百度百科上的解释是:公因数只有1的两个数,叫做互质数。;维基百科上的解释是:互质,又称互素。若N个整数的最大公因子是1,则称这N个整数互质。
常见的互质数判断方法主要有以下几种:
7|12指数运算
7|13模运算
8|0RSA加密算法
8|1公钥和密钥的产生
假设Alice想要通过一个不可靠的媒体接收Bob的一条私人讯息。她可以用以下的方式来产生一个公钥和一个私钥:
8|2加密消息
假设Bob想给Alice送一个消息m,他知道Alice产生的N和e。他使用起先与Alice约好的格式将m转换为一个小于N的整数n,比如他可以将每一个字转换为这个字的Unicode码,然后将这些数字连在一起组成一个数字。假如他的信息非常长的话,他可以将这个信息分为几段,然后将每一段转换为n。用下面这个公式他可以将n加密为c:
ne ≡ c (mod N)
计算c并不复杂。Bob算出c后就可以将它传递给Alice。
8|3解密消息
Alice得到Bob的消息c后就可以利用她的密钥d来解码。她可以用以下这个公式来将c转换为n:
cd ≡ n (mod N)
得到n后,她可以将原来的信息m重新复原。
8|4解码的原理是
cd ≡ n e·d(mod N)
以及
ed ≡ 1 (mod p-1)
和ed ≡ 1 (mod q-1)。
由费马小定理可证明(因为p和q是质数)
n e·d ≡ n (mod p)
和n e·d ≡ n (mod q)
这说明(因为p和q是不同的质数,所以p和q互质)
n e·d ≡ n (mod pq)
8|5签名消息
RSA也可以用来为一个消息署名。假如甲想给乙传递一个署名的消息的话,那么她可以为她的消息计算一个散列值(Message digest),然后用她的密钥(private key)加密这个散列值并将这个“署名”加在消息的后面。这个消息只有用她的公钥才能被解密。乙获得这个消息后可以用甲的公钥解密这个散列值,然后将这个数据与他自己为这个消息计算的散列值相比较。假如两者相符的话,那么他就可以知道发信人持有甲的密钥,以及这个消息在传播路径上没有被篡改过。
9|0Golang加密解密之RSA
9|1概要
这是一个非对称加密算法,一般通过公钥加密,私钥解密。
在加解密过程中,使用openssl生产密钥。执行如下操作:
9|2创建私钥
9|3创建公钥
一般地,各个语言也会提供API,用于生成密钥。在Go中,可以查看
encoding/pem
包和crypto/x509
包。加密解密这块,涉及到很多标准
9|4Go RSA加密
- rsa加解密, 必须会去查crypto/ras这个包
这是该包的说明:实现RSA加密技术,基于PKCS#1规范。
对于什么是PKCS#1,可以查阅相关资料。PKCS(公钥密码标准),而#1就是RSA的标准。可以查看:PKCS系列简介
从该包中函数的名称,可以看到有两对加解密的函数。
这称作加密方案,详细可以查看,PKCS #1 v2.1 RSA 算法标准
可见,当与其他语言交互时,需要确定好使用哪种方案。
PublicKey和PrivateKey两个类型分别代表公钥和私钥,关于这两个类型中成员该怎么设置,这涉及到RSA加密算法,本文中,这两个类型的实例通过解析文章开头生成的密钥得到。
2 . 解析密钥得到PublicKey和PrivateKey的实例
这个过程,我也是花了好些时间(主要对各种加密的各种东东不熟):怎么将openssl生成的密钥文件解析到公钥和私钥实例呢?
在
encoding/pem
包中,看到了—–BEGIN Type—–这样的字样,这正好和openssl生成的密钥形式差不多,那就试试。在该包中,一个block代表的是PEM编码的结构,关于PEM,请查阅相关资料。我们要解析密钥,当然用Decode方法:
这样便得到了一个Block的实例(指针)。
解析来看
crypto/x509
。为什么是x509呢?这又涉及到一堆概念。先不管这些,我也是看encoding和crypto这两个包的子包摸索出来的。
在x509包中,有一个函数:
从该函数的说明:ParsePKIXPublicKey parses a DER encoded public key. These values are typically found in PEM blocks with “BEGIN PUBLIC KEY”。可见这就是解析PublicKey的。另外,这里说到了PEM,可以上面的encoding/pem对了。
而解析私钥的,有好几个方法,从上面的介绍,我们知道,RSA是PKCS#1,刚好有一个方法:
返回的就是rsa.PrivateKey
9|5加密解密实现
加密
解密
使用例子
参考: