共计 3268 个字符,预计需要花费 9 分钟才能阅读完成。
非对称加密算法
1. 对称加密的弊病
- 秘钥散发艰难
-
能够通过非对称加密实现秘钥的散发
Alice 和 Bob 通信,Alice 给 Bob 发送数据,应用对称加密的流程
1.Bob 生成一个非对称的密钥对,
2.Bob 将公钥发送给 Alice
3.Alice 生成一个用于对称加密的秘钥
4.Alice 应用 Bob 的公钥就对对称加密的秘钥进行加密,并发送给 Bob
5.Bob 应用私钥对数据解密,失去对称加密的私钥
通信的单方应用写好的秘钥进行对称加密对数据加密
- 场景剖析
1. 通信流程,信息加密(A 写数据给 B,信息只容许 B 读)
A: 公钥
B:私钥2. 登录认证(客户端要登录,连贯服务器,向服务器申请集体数据)
客户端:私钥
服务端:公钥3. 数字签名(表明信息没有受到篡改,的确是信息拥有者收回来的,附在信息原文的前面)
发送端:私钥
承受端:公钥4. 网银 U 盾
集体:私钥
银行:公钥.
总结: 数据对谁更重要, 谁就拿私钥
2. 非对称加密的秘钥
- 不存在秘钥散发的艰难问题
3. 生成 RSA 的密钥对
-
概念
x509 证书标准、pem、base64- pem 是一种源自窃密加强邮件协定的编码标准,可进行数据加密
- base64 也是一种编码标准,过程可逆
-
无论原始数据是什么,将原始数据应用 64 个字符来代替(a-z、A-Z、0-9、/、+)
ASN.1 形象语法标记
PKCS1 规范
- 密钥对生成流程
私钥生成
1. 应用 rsa 中的 GenerateKey 办法生成私钥
func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error)
- rand.Reader -> import “crypto/rand”
- bits 1024 的整数倍 - 倡议
2. 通过 x509 规范将失去的 rsa 私钥序列化为 ASN.1 的 DER 编码字符串
func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte3. 将私钥字符串设置到 pem 格局块中
初始化一个 pem.Block 块4. 通过 pem 将设置好的数据进行编码,并写入磁盘文件
func Encode(out io.Writer, b *Block) error
out – 筹备一个文件指针
公钥生成
1. 从失去的私钥对象中将公钥信息取出
type PrivateKey struct { PublicKey // 公钥 D *big.Int // 公有的指数 Primes []*big.Int // N 的素因子,至多有两个 // 蕴含事后计算好的值,可在某些状况下减速私钥的操作 Precomputed PrecomputedValues }
2. 通过 x509 规范将失去的 rsa 公钥序列化为字符串
func MarshalPKIXPublicKey(pub interface{}) ([]byte, error)
3. 将公钥字符串设置到 pem 格局块中
4. 通过 pem 将设置好的数据进行编码,并写入磁盘文件
4.RSA 加解密
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"os"
)
// 生成 rsa 私钥和公钥并写入磁盘文件
func GenerateRsaKey(keySize int) {
//1. 生成 rsa 秘钥
privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
if err != nil {panic(err)
}
//2. 通过 x509 规范将失去的 rsa 私钥序列化为 ASN.1 的 DER 编码字符串
derText := x509.MarshalPKCS1PrivateKey(privateKey)
//3. 创立一个 pem.Block 构造体
block := pem.Block{
Type: "rsa private key",
Bytes: derText,
}
//4. 通过 pem 将设置好的私钥数据进行编码,并写入磁盘文件
file, err := os.Create("private.pem")
if err != nil {panic(err)
}
err = pem.Encode(file, &block)
if err != nil {panic(err)
}
// ========== 公钥 ==================
//1. 从私钥中取出公钥
publicKey := privateKey.PublicKey
//2. 应用 x509 序列化公钥为字符串
marshalPKIXPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {panic(err)
}
//3. 通过公钥字符串设置到 pem 格局块中
block = pem.Block{
Type: "rsa public key",
Headers: nil,
Bytes: marshalPKIXPublicKey,
}
//4.pem 编码
file, err = os.Create("public.pem")
if err != nil {panic(err)
}
err = pem.Encode(file, &block)
if err != nil {panic(err)
}
file.Close()}
//rsa 加密
func RSAEncrypt(plainText []byte, fileName string) []byte {
//1. 关上公钥文件
file, err := os.Open(fileName)
if err != nil {panic(err)
}
fileInfo, err := file.Stat()
if err != nil {panic(err)
}
buf := make([]byte, fileInfo.Size())
_, err = file.Read(buf)
if err != nil {panic(err)
}
file.Close()
//2.pem decode
block, _ := pem.Decode(buf)
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {panic(err)
}
pubKey := publicKey.(*rsa.PublicKey)
//3. 应用公钥加密
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, plainText)
if err != nil {panic(err)
}
return cipherText
}
//rsa 解密
func RSADecrypt(cipherText []byte, fileName string) []byte {
//1. 关上私钥文件
file, err := os.Open(fileName)
if err != nil {panic(err)
}
fileInfo, err := file.Stat()
if err != nil {panic(err)
}
buf := make([]byte, fileInfo.Size())
_, err = file.Read(buf)
if err != nil {panic(err)
}
//2.pem decode
block, _ := pem.Decode(buf)
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {panic(err)
}
//3. 解密数据
plainText, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
if err != nil {panic(err)
}
return plainText
}
func main() {GenerateRsaKey(1024)
src := []byte("解决了秘钥散发的艰难问题, 不能加密稍长一点的数据,次要用来加密对称秘钥")
cipherText := RSAEncrypt(src, "public.pem")
plainText := RSADecrypt(cipherText, "private.pem")
fmt.Println("解密后果:", string(plainText))
}