RSA 笔记总结
一、RSA加密简介
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。
二、RSA加密、签名区别
加密和签名都是为了安全性考虑,但略有不同。常有人问加密和签名是用私钥还是公钥?其实都是对加密和签名的作用有所混淆。简单的说,加密是为了防止信息被泄露,而签名是为了防止信息被篡改。这里举2个例子说明。
第一个场景:战场上,B要给A传递一条消息,内容为某一指令。
RSA的加密过程如下:
(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
(2)A传递自己的公钥给B,B用A的公钥对消息进行加密。
(3)A接收到B加密的消息,利用A自己的私钥对消息进行解密。
在这个过程中,只有2次传递过程,第一次是A传递公钥给B,第二次是B传递加密消息给A,即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行解密,防止了消息内容的泄露。
第二个场景:A收到B发的消息后,需要进行回复“收到”。
RSA签名的过程如下:
(1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
(2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。
(3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。
在这个过程中,只有2次传递过程,第一次是A传递加签的消息和消息本身给B,第二次是B获取A的公钥,即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行签名,即使知道了消息内容,也无法伪造带签名的回复给B,防止了消息内容的篡改。
但是,综合两个场景你会发现,第一个场景虽然被截获的消息没有泄露,但是 一旦截获的公钥,将假指令进行加密,然后传递给A, A并不能识别是否是假消息。
第二个场景虽然 消息不能被篡改,但是消息的内容是明文的 并不能防止泄露。所以在实际应用中,要根据情况使用,也可以同时使用加密和签名,比如A和B都有一套自己的公钥和私钥,当A要给B发送消息时,先用B的公钥对关键消息加密,再对加密的消息使用A的私钥加签名,即 先加密后签名 达到既不泄露也不被篡改,更能保证消息的安全性。
总结:公钥加密、私钥解密、私钥签名、公钥验签。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | func GenKeyPairs() (string, string, error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return "" , "" , err } priStream := x509.MarshalPKCS1PrivateKey(privateKey) block := &pem.Block{ Type: "RSA PRIVATE KEY" , Bytes: priStream, } priKey := pem.EncodeToMemory(block) pubStream, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey) if err != nil { return "" , "" , err } block = &pem.Block{ Type: "RSA PRIVATE KEY" , Bytes: pubStream, } pubKey := pem.EncodeToMemory(block) if err != nil { return "" , "" , err } return string(priKey), string(pubKey), nil } // / // encryption sign // 公钥加密/ func RsaEncrypt(data []byte, keyBytes []byte) (msg []byte, err error) { //解密pem格式的公钥 block, _ := pem.Decode(keyBytes) if block == nil { return nil, errors.New( "public key error" ) } pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, err } // 类型断言 pubKey := pubInterface.(*rsa.PublicKey) //加密 text, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, data) if err != nil { return nil, err } return text, nil } // RsaDecrypt 私钥解密 func RsaDecrypt(text, keyBytes []byte) ([]byte, error) { //获取私钥 block, _ := pem.Decode(keyBytes) if block == nil { return nil, errors.New( "private key error" ) } //解析PKCS1格式的私钥 privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, err } // 解密 data, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, text) if err != nil { return nil, err } return data, nil } //私钥签名 func RsaSignWithSha256(data []byte, keyBytes []byte) []byte { h := sha256.New() h.Write(data) hashed := h.Sum(nil) block, _ := pem.Decode(keyBytes) if block == nil { panic(errors.New( "private key error" )) } privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { fmt.Println( "ParsePKCS8PrivateKey err" , err) panic(err) } signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed) if err != nil { fmt.Printf( "Error from signing: %s\n" , err) panic(err) } return signature } // 公钥验证 func RsaVerySignWithSha256(data, signData, keyBytes []byte) bool { block, _ := pem.Decode(keyBytes) if block == nil { panic(errors.New( "public key error" )) } pubKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { panic(err) } hashed := sha256.Sum256(data) err = rsa.VerifyPKCS1v15(pubKey.(*rsa.PublicKey), crypto.SHA256, hashed[:], signData) if err != nil { panic(err) } return true } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现