forked from golang/hotime
144 lines
3.5 KiB
Go
144 lines
3.5 KiB
Go
|
package rsa
|
|||
|
|
|||
|
import (
|
|||
|
"crypto/rand"
|
|||
|
"crypto/rsa"
|
|||
|
"crypto/x509"
|
|||
|
"encoding/asn1"
|
|||
|
"encoding/pem"
|
|||
|
"fmt"
|
|||
|
"os"
|
|||
|
)
|
|||
|
|
|||
|
func FileGet(path string) []byte {
|
|||
|
file, err := os.Open(path)
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
defer file.Close()
|
|||
|
//读取文件的内容
|
|||
|
info, _ := file.Stat()
|
|||
|
buf := make([]byte, info.Size())
|
|||
|
file.Read(buf)
|
|||
|
return buf
|
|||
|
}
|
|||
|
|
|||
|
//RSA加密
|
|||
|
// plainText 要加密的数据
|
|||
|
// path 公钥匙文件地址
|
|||
|
func RSA_Encrypt(plainText []byte, buf []byte) []byte {
|
|||
|
//pem解码
|
|||
|
block, _ := pem.Decode(buf)
|
|||
|
//x509解码
|
|||
|
|
|||
|
publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
//类型断言
|
|||
|
publicKey := publicKeyInterface.(*rsa.PublicKey)
|
|||
|
//对明文进行加密
|
|||
|
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
//返回密文
|
|||
|
return cipherText
|
|||
|
}
|
|||
|
|
|||
|
//RSA解密
|
|||
|
// cipherText 需要解密的byte数据
|
|||
|
// path 私钥文件路径
|
|||
|
func RSA_Decrypt(cipherText []byte, buf []byte) []byte {
|
|||
|
|
|||
|
//pem解码
|
|||
|
block, _ := pem.Decode(buf)
|
|||
|
//X509解码
|
|||
|
private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
|||
|
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
//对密文进行解密
|
|||
|
//plainText,_:=rsa.DecryptPKCS1v15(rand.Reader,privateKey,cipherText)
|
|||
|
|
|||
|
v, err := rsa.DecryptPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), cipherText)
|
|||
|
//返回明文
|
|||
|
return v
|
|||
|
}
|
|||
|
func MarshalPKCS8PrivateKey(key *rsa.PrivateKey) []byte {
|
|||
|
info := struct {
|
|||
|
Version int
|
|||
|
PrivateKeyAlgorithm []asn1.ObjectIdentifier
|
|||
|
PrivateKey []byte
|
|||
|
}{}
|
|||
|
info.Version = 0
|
|||
|
info.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 1)
|
|||
|
info.PrivateKeyAlgorithm[0] = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
|
|||
|
info.PrivateKey = x509.MarshalPKCS1PrivateKey(key)
|
|||
|
|
|||
|
k, err := asn1.Marshal(info)
|
|||
|
if err != nil {
|
|||
|
panic(err.Error())
|
|||
|
}
|
|||
|
return k
|
|||
|
}
|
|||
|
|
|||
|
func Demo() {
|
|||
|
//生成密钥对,保存到文件
|
|||
|
GenerateRSAKey(2048, "./")
|
|||
|
//加密
|
|||
|
data := []byte("hello world")
|
|||
|
encrypt := RSA_Encrypt(data, FileGet("public.pem"))
|
|||
|
fmt.Println(string(encrypt))
|
|||
|
|
|||
|
// 解密
|
|||
|
decrypt := RSA_Decrypt(encrypt, FileGet("private.pem"))
|
|||
|
fmt.Println(string(decrypt))
|
|||
|
}
|
|||
|
|
|||
|
//生成RSA私钥和公钥,保存到文件中
|
|||
|
// bits 证书大小
|
|||
|
func GenerateRSAKey(bits int, path string) {
|
|||
|
//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
|
|||
|
//Reader是一个全局、共享的密码用强随机数生成器
|
|||
|
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
//保存私钥
|
|||
|
//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
|
|||
|
X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
|
|||
|
//使用pem格式对x509输出的内容进行编码
|
|||
|
//创建文件保存私钥
|
|||
|
privateFile, err := os.Create(path + "private.pem")
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
defer privateFile.Close()
|
|||
|
//构建一个pem.Block结构体对象
|
|||
|
privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey}
|
|||
|
//将数据保存到文件
|
|||
|
pem.Encode(privateFile, &privateBlock)
|
|||
|
|
|||
|
//保存公钥
|
|||
|
//获取公钥的数据
|
|||
|
publicKey := privateKey.PublicKey
|
|||
|
//X509对公钥编码
|
|||
|
X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
//pem格式编码
|
|||
|
//创建用于保存公钥的文件
|
|||
|
publicFile, err := os.Create(path + "public.pem")
|
|||
|
if err != nil {
|
|||
|
panic(err)
|
|||
|
}
|
|||
|
defer publicFile.Close()
|
|||
|
//创建一个pem.Block结构体对象
|
|||
|
publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey}
|
|||
|
//保存到文件
|
|||
|
pem.Encode(publicFile, &publicBlock)
|
|||
|
}
|