ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

go 密码学

2022-05-31 12:01:01  阅读:170  来源: 互联网

标签:return nil err go 加密 byte 密码学 string


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有