go 密码学
作者:互联网
go 密码学
1.1 对称加密
加密过程的每一步都是可逆的。加密和解密用的是同一组密钥。异或是最简单的对称加密算法。
DES(Data Encryption Standard)数据加密标准,是目前最为流行的加密算法之一。对原始数据(明文)进行分组,每组64位,最后一组不足64位时按一定规则填充。每一组上单独施加DES算法。
DES子密钥生成
初始密钥64位,实际有效位56位,每隔7位有一个校验位。根据初始密钥生成16个48位的子密钥。我们可以看到下面的置换表是没有8或者8的倍数
N取值从1到16,N和x有固定的映射表。
DES加密过程
L1, R1 = f(L0, R0, K1),依此循环,得到L16和R16。
S盒替换。输入48位,输出32位。各分为8组,输入每组6位,输出每组4位。分别在每组上施加S盒替换,一共8个S盒。
DES加密过程
//XOR 异或运算,要求plain和key的长度相同
func XOR(plain string, key []byte) string {
bPlain := []byte(plain)
bCipher := make([]byte, len(key))
for i, k := range key {
bCipher[i] = k ^ bPlain[i]
}
cipher := string(bCipher)
return cipher
}
分组模式。CBC(Cipher Block Chaining )密文分组链接模式,将当前明文分组与前一个密文分组进行异或运算,然后再进行加密。其他分组模式还有ECB, CTR, CFR, OFB。
func DesEncryptCBC(text string, key []byte) (string, error) {
src := []byte(text)
block, err := des.NewCipher(key) //用des创建一个加密器cipher
if err != nil {
return "", err
}
blockSize := block.BlockSize() //分组的大小,blockSize=8
src = common.ZeroPadding(src, blockSize) //填充
out := make([]byte, len(src)) //密文和明文的长度一致
encrypter := cipher.NewCBCEncrypter(block, key) //CBC分组模式加密
encrypter.CryptBlocks(out, src)
return hex.EncodeToString(out), nil
}
func DesDecryptCBC(text string, key []byte) (string, error) {
src, err := hex.DecodeString(text) //转成[]byte
if err != nil {
return "", err
}
block, err := des.NewCipher(key)
if err != nil {
return "", err
}
out := make([]byte, len(src)) //密文和明文的长度一致
encrypter := cipher.NewCBCDecrypter(block, key) //CBC分组模式解密
encrypter.CryptBlocks(out, src)
out = common.ZeroUnPadding(out) //反填充
return string(out), nil
}
AES(Advanced Encryption Standard)高级加密标准,旨在取代DES。
2.1 非对称加密
- 使用公钥加密,使用私钥解密。
- 公钥和私钥不同。
- 公钥可以公布给所有人。
- 私钥只有自己保存。
- 相比于对称加密,运算速度非常慢。
对称加密和非对称加密结合使用的案例。小明要给小红传输机密文件,他俩先交换各自的公钥,然后: - 小明生成一个随机的AES口令,然后用小红的公钥通过RSA加密这个口令,并发给小红。
- 小红用自己的RSA私钥解密得到AES口令。
- 双方使用这个共享的AES口令用AES加密通信。
RSA是三个发明人名字的缩写:Ron Rivest,Adi Shamir,Leonard Adleman。密钥越长,越难破解。 目前768位的密钥还无法破解(至少没人公开宣布)。因此可以认为1024位的RSA密钥基本安全,2048位的密钥极其安全。RSA的算法原理主要用到了数论。
- RSA加密过程
- 随机选择两个不相等的质数p和q。p=61, q=53
- 计算p和q的乘积n。n=3233
- 计算n的欧拉函数φ(n) = (p-1)(q-1)。 φ(n) =3120
- 随机选择一个整数e,使得1< e < φ(n),且e与φ(n) 互质。e=17
- 计算e对于φ(n)的模反元素d,即求解ed+ φ(n)y=1。d=2753, y=-15
- 将n和e封装成公钥,n和d封装成私钥。公钥=(3233,17),公钥=(3233,2753)
// RSA加密
func RsaEncrypt(origData []byte) ([]byte, error) {
//解密pem格式的公钥
block, _ := pem.Decode(publicKey)
if block == nil {
return nil, errors.New("public key error")
}
// 解析公钥
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) //目前的数字证书一般都是基于ITU(国际电信联盟)制定的X.509标准
if err != nil {
return nil, err
}
// 类型断言
pub := pubInterface.(*rsa.PublicKey)
//加密
return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}
// RSA解密
func RsaDecrypt(ciphertext []byte) ([]byte, error) {
//解密
block, _ := pem.Decode(privateKey)
if block == nil {
return nil, errors.New("private key error!")
}
//解析PKCS1格式的私钥
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
// 解密
return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}
ECC(Elliptic Curve Cryptography)椭圆曲线加密算法,相比RSA,ECC可以使用更短的密钥,来实现与RSA相当或更高的安全。定义了椭圆曲线上的加法和二倍运算。椭圆曲线依赖的数学难题是:k为正整数,P是椭圆曲线上的点(称为基点), k*P=Q , 已知Q和P,很难计算出k。
func genPrivateKey() (*ecies.PrivateKey, error) {
pubkeyCurve := elliptic.P256() // 初始化椭圆曲线
// 随机挑选基点,生成私钥
p, err := ecdsa.GenerateKey(pubkeyCurve, rand.Reader) //用golang标准库生成公私钥对
if err != nil {
return nil, err
} else {
return ecies.ImportECDSA(p), nil //转换成以太坊的公私钥对
}
}
//ECCEncrypt 椭圆曲线加密
func ECCEncrypt(plain string, pubKey *ecies.PublicKey) ([]byte, error) {
src := []byte(plain)
return ecies.Encrypt(rand.Reader, pubKey, src, nil, nil)
}
//ECCDecrypt 椭圆曲线解密
func ECCDecrypt(cipher []byte, prvKey *ecies.PrivateKey) (string, error) {
if src, err := prvKey.Decrypt(cipher, nil, nil); err != nil {
return "", err
} else {
return string(src), nil
}
}
3.1 hash算法
哈希函数的基本特征
- 输入可以是任意长度。
- 输出是固定长度。
- 根据输入很容易计算出输出。
- 根据输出很难计算出输入(几乎不可能)。
- 两个不同的输入几乎不可能得到相同的输出。
SHA(Secure Hash Algorithm) 安全散列算法,是一系列密码散列函数,有多个不同安全等级的版本:SHA-1,SHA-224,SHA-256,SHA-384,SHA-512。其作用是防伪装,防窜扰,保证信息的合法性和完整性。
sha-1算法大致过程 - 填充。使得数据长度对512求余的结果为448。
- 在信息摘要后面附加64bit,表示原始信息摘要的长度。
- 初始化h0到h4,每个h都是32位。
- h0到h4历经80轮复杂的变换。
- 把h0到h4拼接起来,构成160位,返回。
func Sha1(data string) string {
sha1 := sha1.New()
sha1.Write([]byte(data))
return hex.EncodeToString(sha1.Sum(nil))
}
MD5(Message-Digest Algorithm 5)信息-摘要算法5,算法流程跟SHA-1大体相似。MD5的输出是128位,比SHA-1短了32位。MD5相对易受密码分析的攻击,运算速度比SHA-1快。
func Md5(data string) string {
md5 := md5.New()
md5.Write([]byte(data))
return hex.EncodeToString(md5.Sum(nil))
}
哈希函数的应用场景
- 用户密码的存储。
- 文件上传/下载完整性校验。
- mysql大字段的快速对比。 数字签名
比特币中验证交易记录的真实性用的就是数字签名。先hash再用私钥加密的原因是:非对称加密计算量比较大,先hash可以把原始数据转一条很短的信息,提高计算效率。
标签:return,nil,err,go,加密,byte,密码学,string 来源: https://www.cnblogs.com/liwenchao1995/p/16329964.html