其他分享
首页 > 其他分享> > go 密码学

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 非对称加密

RSA是三个发明人名字的缩写:Ron Rivest,Adi Shamir,Leonard Adleman。密钥越长,越难破解。 目前768位的密钥还无法破解(至少没人公开宣布)。因此可以认为1024位的RSA密钥基本安全,2048位的密钥极其安全。RSA的算法原理主要用到了数论。

// 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算法

哈希函数的基本特征

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))
}

哈希函数的应用场景

比特币中验证交易记录的真实性用的就是数字签名。先hash再用私钥加密的原因是:非对称加密计算量比较大,先hash可以把原始数据转一条很短的信息,提高计算效率。

标签:return,nil,err,go,加密,byte,密码学,string
来源: https://www.cnblogs.com/liwenchao1995/p/16329964.html