文章目录
一、相关知识扫盲篇
数字签名、数字证书
A与B的交互,通过一方的公私密钥,实现数据的加密,解密,验证数据签名,以保证其数据是对的。
但是存在比如B处存放的A的公钥被别人替换为如C的公钥可能性,这样C去发送信息给B,B会误以为是A发的,达到欺骗的效果
由此出现了,中心证书的CA(Certificate authority)机构,做中间人,把公钥持有人的信息,再用机构的私钥对A的信息进行加密。
B拿到数据,先用证书持有机构的公钥进行解密,证明是A的数据,然后再用A的公钥进行验签
引申:既然道格可以替换鲍勃的公钥,为什么不能故技重施,伪造CA的公钥,然后用自己的私钥伪造成CA的数字证书,从而达到欺骗苏珊的目的呢?
解释:CA的公钥是公开的,是可查的,他们的公钥在自己网站上提供下载,因此无法伪造
总结:公私钥用于加密、验证之间的数据,证书(中心媒介)用于证明其拿到的是正确的交互方的公钥。
防止证书伪造 之 证书链-Digital Certificates
SHA256withRSA
先用RAS加密,在执行SHA256的哈希运算,主要用在签名验证操作
二、公私钥格式、协议规范
- 公私钥格式、标准、规范,golang生成公私钥,见(https://blog.csdn.net/BuquTianya/article/details/82958194)
- openssl数字证书常见格式与协议介绍
主要涉及的go包:
x509
x509包解析X.509(密码学里公钥证书的格式标准)编码的证书和密钥pem
包,pem包实现了PEM数据编码(源自保密增强邮件协议 Privacy Enbanced Mail)。目前PEM编码主要用于TLS密钥和证书crypto/rsa
rsa包实现了PKCS#1规定的RSA加密算法
三、golang RSA加密、解密具体实现
RSA
加密、解密
RSA
加密数据- 再配合
SHA256
哈希 获得不可修改的签名signature
RSA
公钥加密
// 公钥加密-分段
func RsaEncryptBlock(src, publicKeyByte []byte) (bytesEncrypt []byte, err error) {
// 解码公钥文件,返回block结构
// The encoded form is:
// -----BEGIN Type-----
// Headers
// base64-encoded Bytes
// -----END Type-----
block, _ := pem.Decode(publicKeyByte)
if block == nil {
return nil, errors.New("Decode PublicKey Fail")
}
// 解析 PKIX 格式的公钥,返回 *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey 等格式的struct
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
//根据自己具体使用的格式做推测
pub, keySize := publicKey.(*rsa.PublicKey), publicKey.(*rsa.PublicKey).Size()
srcSize := len(src)
fmt.Println("密钥长度:", keySize, "\t明文长度:\t", srcSize)
//单次加密的长度需要减掉padding的长度,PKCS1为11
// 按需加密
offSet, once := 0, keySize-11
buffer := bytes.Buffer{
}
for offSet < srcSize {
endIndex := offSet + once
if endIndex > srcSize {
endIndex = srcSize
}
// 加密一部分
bytesOnce, err := rsa.EncryptPKCS1v15(myrand.Reader, pub, src[offSet:endIndex])
if err != nil {
return nil, err
}
buffer.Write(bytesOnce)
offSet = endIndex
}
bytesEncrypt = buffer.Bytes()