加密之数字签名
在说数字签名之前
先说一下 消息认证码 的局限性
A和B都持有密钥
所以不能判断消息是由A生成的还是B生成的
所以可以这样
A持有一个私钥,B持有一个公钥
只有A才可以生成消息,B只能验证消息
这样的话就可以保证消息都是A生成的
这就是数字签名的技术
非对称加密 和 数字签名
假设有A 和 B C D
非对称加密是
B C D持有公钥,进行加密
A持有私钥,可以解密
只有A可以解密
数字签名是
A持有私钥,可以进行加密
B C D持有公钥,可以进行认证
我们来说说
通过RSA来实现 数字签名
在进行数字签名之前
我们需要通过代码来生成公钥和私钥
func generateRsaKeyPair(bits int) error {
//1. GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥。
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return err
}
fmt.Printf("创建私钥中...\n")
//2. MarshalPKCS1PrivateKey将rsa私钥序列化为ASN.1 PKCS#1 DER编码。
derTextPri := x509.MarshalPKCS1PrivateKey(privateKey)
//3. 创建一个pem格式的block结构,将der编码的字节流写入block
block := pem.Block{
Type: "RSA Private Key",
Headers: nil,
Bytes: derTextPri,
}
file1, err := os.Create("rsaPrivateKey.pem")
if err != nil {
return err
}
defer file1.Close()
//4. 使用pem的Encode方法,将block写入磁盘文件中
err = pem.Encode(file1, &block)
if err != nil {
return err
}
fmt.Printf("创建公钥中...\n")
//1. 通过私钥获得公钥
publicKey := privateKey.PublicKey
//2. MarshalPKCS1PublicKey将rsa私钥序列化为ASN.1 PKCS#1 DER编码。
derTextPub := x509.MarshalPKCS1PublicKey(&publicKey)
//3. 创建一个pem格式的block结构,将der编码的字节流写入block
blockPub := pem.Block{
Type: "RSA Publick Key",
Headers: nil,
Bytes: derTextPub,
}
file2, err := os.Create("rsaPublicKey.pem")
if err != nil {
return err
}
defer file2.Close()
//4. 使用pem的Encode方法,将block写入磁盘文件中
err = pem.Encode(file2, &blockPub)
if err != nil {
return err
}
return nil
}
func main() {
err := generateRsaKeyPair(2048)
if err != nil {
fmt.Printf("创建rsa秘钥对失败:%s\n", err)
}
fmt.Printf("创建rsa秘钥对成功!")
}
生成了公钥和私钥
然后我们来生成数字签名
然后验证一下
func rsaPubKeyEncrypt(src []byte, fileName string) []byte {
//1. 从公钥文件读取文件,得到pem编码后的数据
//os.Open()
buffer, err := ioutil.ReadFile(fileName)
if err != nil {
panic(err)
}
//2. 对数据进行解码(Decode)得到Block
//func Decode(data []byte) (p *Block, rest []byte)
block, _ := pem.Decode(buffer)
//3. 得到Block中的Bytes,即DER格式的字节流
derText := block.Bytes
//4. 解析字节流,得到公钥
//parsePKCSPublickKey(der []byte)(public *rsa.PublicKey)
publicKey, err := x509.ParsePKCS1PublicKey(derText)
if err != nil {
panic(err)
}
//5. 使用公钥进行加密
//func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error)
cipherData, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src)
if err != nil {
panic(err)
}
return cipherData
}
func rsaPriKeyDecrypt(cipherData []byte, fileName string) []byte {
//1. 从私钥文件读取数据,得到pem编码后的数据
buffer, err := ioutil.ReadFile(fileName)
if err != nil {
panic(err)
}
//2. 对数据进行解码(Decode)得到Block
//func Decode(data []byte) (p *Block, rest []byte)
block, _ := pem.Decode(buffer)
//3. 得到Block中的Bytes,即DER格式的字节流
derText := block.Bytes
//4. 解析字节流,得到公钥
privateKey, err := x509.ParsePKCS1PrivateKey(derText)
if err != nil {
panic(err)
}
//5. 使用私钥进行解密
//func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error)
plainText, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherData)
if err != nil {
panic(err)
}
return plainText
}
func main() {
src := []byte("你好 世界 hello world")
fmt.Printf("原文:%s\n", src)
cipherData := rsaPubKeyEncrypt(src, "./rsaPublicKey.pem")
fmt.Printf("cipherData : %x\n", cipherData)
plainText := rsaPriKeyDecrypt(cipherData, "./rsaPrivateKey.pem")
fmt.Printf("plainText : %s\n", plainText)
}