RSA

目录

1.1 RSA简介

1.2 RSA图解

1.3 RSA加密

1.4 RSA解密

1.5 图解RSA加密解密

1.6 Golang生成公钥和私钥

1.7 Golang使用RSA


1.1 RSA简介

RSA是一种非对称加密算法,它的名字是由它的三位开发者,即RonRivest、AdiShamir和LeonardAdleman 的姓氏的首字母组成的(Rivest-Shamir-Leonard)。

RSA可以被用于非对称加密和数字签名。

1.2 RSA图解

RSA

1.3 RSA加密

RSA

  • 对代表明文的数字的E次方求modN的结果。就是将明文自己做E次乘法,然后将其结果除以N求余数,这个余数就是密文。
  • E和N的组合就是公钥。
  • E是加密(Encryption)的首字母,N是数字(Number)的首字母。
  • RSA的加密就是 “求E次方的modN"

1.4 RSA解密

RSA

  • 对表示密文的数字的D次方求modN就可以得到明文。将密文自己做D次乘法,再对其结果除以N求余数,就可以得到明文。
  • 数D和数N组合起来就是RSA的解***,因此D和N的组合就是私钥
  • 在RSA中,加密和解密的形式是相同的。加密是求 "E次方的mod N”,而解密则是求 "D次方的modN” 。
  • D是解密〈Decryption)的首字母,N是数字(Number)的首字母

1.5 图解RSA加密解密

RSA

1.6 Golang生成公钥和私钥

  •  生成私钥流程:
  1. 使用rsa包中的GenerateKey方法生成私钥
  2. 通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
  3. 将私钥字符串设置到pem格式块中
  4. 通过pem将设置好的数据进行编码, 并写入磁盘文件中
  •  生成公钥流程:
  1. 从得到的私钥对象中将公钥信息取出
  2. 通过x509标准将得到 的rsa公钥序列化为字符串
  3. 将公钥字符串设置到pem格式块中
  4. 通过pem将设置好的数据进行编码, 并写入磁盘文件
  • 示例
/**
*
*	!rsa 生成秘钥对函数	GenerateRsaKey  孙东
*	@parmas(int)
*	@return(nil)
*
 */
func GenerateRsaKey(keySize int) {
	//01.	使用rsa中的GenerateKey方法生成私钥
	privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
	//02.	nil
	if err != nil {
		panic(err)
	}
	//03.	通过x509标准获取ras私钥序列化为ASN.1的der编码字符串
	derText := x509.MarshalPKCS1PrivateKey(privateKey)
	//04.	需要组织一个pem.block
	block := pem.Block{
		Type:  "rsa private key", //标题
		Bytes: derText,
	}
	//05.	pem编码
	file, err := os.Create("private.pem")
	if err != nil {
		panic(err)
	}
	//06.	pem处理
	pem.Encode(file, &block)
	//关闭流
	file.Close()
	//***公钥处理
	//01.	从私钥中取出公钥
	publickey := privateKey.PublicKey
	//02.	使用x509标准序列化
	derstream, err2 := x509.MarshalPKIXPublicKey(&publickey)
	if err2 != nil {
		panic(err)
	}
	//03.	将的要的数据放到pem.block中
	block = pem.Block{
		Type:  "rsa public key",
		Bytes: derstream,
	}
	//04.	pem编码
	file, err = os.Create("public.pem")
	if err != nil {
		panic(err)
	}
	pem.Encode(file, &block)
	//05.	文件关闭
}
  • 重要函数:
  1. GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA**。
    "crypto/rsa" 包中的函数
    func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error)
        - 参数1: io.Reader: 赋值为: rand.Reader
            -- rand包实现了用于加解密的更安全的随机数生成器。
            -- var Reader io.Reader (rand包中的变量)
        - 参数2: bits: 秘钥长度
        - 返回值1: 代表一个RSA私钥。
        - 返回值2: 错误信息
  2. 通过x509 将rsa私钥序列化为ASN.1 PKCS#1 DER编码。
    "crypto/x509" 包中的函数 (x509包解析X.509编码的证书和**)。
    func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte
        - 参数1: 通过rsa.GenerateKey得到的私钥
        - 返回值: 将私钥通过ASN.1序列化之后得到的私钥编码数据

     

  3. 设置Pem编码结构。
    Block代表PEM编码的结构。
    type Block struct {
        Type    string            // 得自前言的类型(如"RSA PRIVATE KEY")
        Headers map[string]string // 可选的头项,Headers是可为空的多行键值对。
        Bytes   []byte            // 内容解码后的数据,一般是DER编码的ASN.1结构
    }

     

  4. 将得到的Pem格式私钥通过文件指针写入磁盘中。
    "encoding/pem" 包中的函数
    func Encode(out io.Writer, b *Block) error
        - 参数1: 可进行写操作的IO对象, 此处需要指定一个文件指针
        - 参数2: 初始化完成的Pem块对象, 即Block对象

     

  5. 通过RSA私钥得到公钥。
    // 私钥
    type PrivateKey struct {
        PublicKey            // 公钥
        D         *big.Int   // 私有的指数
        Primes    []*big.Int // N的素因子,至少有两个
        // 包含预先计算好的值,可在某些情况下加速私钥的操作
        Precomputed PrecomputedValues
    }
    // 公钥
    type PublicKey struct {
        N   *big.Int // 模
        E   int      // 公开的指数
    }
    通过私钥获取公钥
    publicKey := privateKey.PublicKey // privateKey为私钥对象

     

  6. 通过x509将公钥序列化为PKIX格式DER编码。
    "crypto/x509" 包中的函数
    func MarshalPKIXPublicKey(pub interface{}) ([]byte, error)
        - 参数1: 通过私钥对象得到的公钥
        - 返回值1:将公钥通过ASN.1序列化之后得到的编码数据
        - 返回值2: 错误信息

     

  7. 将公钥编码之后的数据格式化为Pem结构, 参考私钥的操作。
  8. 将得到的Pem格式公钥通过文件指针写入磁盘中。
  9. 生成的私钥和公钥文件数据。
    // 私钥文件数据
    -----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQC5bm0DCEV+EFeiLUqSshziqhSB30jXy5BWbPV5SlMq4aWiEknM
    i+Mw1aXic4bEsM3YyT73eWsifqZNSc/4fRaV4qz5OL8IIe9AZoGDSLX/Ar9AQMJf
    OHbAtdIlCGQ4d80KjpDpPs2wZkTqllWCg31d7U3DVEm5kqTGtSYIu9e7JQIDAQAB
    AoGARGdn72ZtvENrEHiEufjajwMO7Zng1TpS1I79PvEcHQWAhHkaoEo6VRl7SD41
    yPkv9njGsaQo0WDHGFvSTGhYm/EWGrBWRPc5xXbSBg7ty9Iza9B1ekAj8VfWryen
    Wje3xDOCVCDUiCcYdaSfPiJPYuWMSnNMNa+0cR921zBQg0ECQQDpCMljuH7LrpbC
    NDF5q+LbUWMAE2KLDPX4WmDSdZdIO3mPux3MdwOUEfrcvSBGZNB7gyaEG7goZL8G
    BqL22MJHAkEAy7SqbVPoPbMPHuLI52VQ2FDp6xxSWLhjmv1ePCHGo28MDCaHeVzZ
    QaxyuIbnY8A6NHfu/QGwz/eB941IjYNBMwJBAI9XEEl+mr++zIz4fdZRnGE7VqId
    SmgtuL7jGNtb6YpMyyFV/6ZdLp5N0PkmfEvQh0zyBycLxeNS1Q1n16Xu/tECQQCZ
    dF42wdDgOfWYFMu31VETw9CTtuApya3vYhMNRXx4Pf1bYeMIf/OCT8CUVbwWHwc5
    42d73TwvTorvy9TuFgSVAkEA6F69THlTn5oIP8IWHcHuqS01fIR/vGfEwQ4cFZGR
    ketfieyeeF8rjn4qzwT/ugwRNjkhfKmoILnIC8UhEEJdjA==
    -----END RSA PRIVATE KEY-----
    // 公钥文件数据
    -----BEGIN RSA PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5bm0DCEV+EFeiLUqSshziqhSB
    30jXy5BWbPV5SlMq4aWiEknMi+Mw1aXic4bEsM3YyT73eWsifqZNSc/4fRaV4qz5
    OL8IIe9AZoGDSLX/Ar9AQMJfOHbAtdIlCGQ4d80KjpDpPs2wZkTqllWCg31d7U3D
    VEm5kqTGtSYIu9e7JQIDAQAB
    -----END RSA PUBLIC KEY-----

     

1.7 Golang使用RSA

  • 公钥加密流程
  1. 将公钥文件中的公钥读出, 得到使用pem编码的字符串 。
  2. 将得到的字符串解码 。
  3. 使用x509将编码之后的公钥解析出来 。
  4. 使用得到的公钥通过rsa进行数据加密 。
  • 私钥解密流程
  1. 将私钥文件中的私钥读出, 得到使用pem编码的字符串 。
  2. 将得到的字符串解码 。
  3. 使用x509将编码之后的私钥解析出来 。
  4. 使用得到的私钥通过rsa进行数据解密 。
  •  公钥加密示例:
    /**
    *
    *	!rsa 公钥加密函数	RsaEncrypt bos2967
    *	@parmas(text,[]byte)
    *	@return([]byte )
    *
     */
    func RsaEncrypt(text string, filename []byte) []byte {
    	//01.	  根据文件名将文件内容从文件中读取出来
    	file, err := os.Open(text)
    	//02.	读文件
    	if err != nil {
    		panic(err)
    	}
    	//03.	读文件
    	FileInfo, err2 := file.Stat() //stat函数 返回( fileinfo, err)
    	if err2 != nil {
    		panic(err2)
    	}
    	//04.	buffer  对接要读取的数据
    	buffer := make([]byte, FileInfo.Size())
    	//
    	n, err3 := file.Read(buffer)
    	if err3 != nil {
    		panic(err3)
    	}
    	defer file.Close()
    	//
    	fmt.Println("--------------------", n)
    	//05.	从数据中查找到下一个pem格式的块
    	block, _ := pem.Decode(buffer)
    	if block == nil {
    		return nil
    	}
    	//06.	解析一个der编码的公钥
    	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    	if err != nil {
    		return nil
    	}
    	pubKey := pubInterface.(*rsa.PublicKey)
    	//07.	公钥加密
    	result, _ := rsa.EncryptPKCS1v15(rand.Reader, pubKey, text)
    	//08.	返回加密后的数据
    	return result
    }

私钥解密示例:

/**
*
*	!rsa 私钥解密函数	RsaDecrypt
*	@pma(text,[]byte)
*	@return([]byte )
*
 */
func RsaDecrypt(text string, fileName []byte) []byte {
	//01.	  根据文件名将文件内容从文件中读取出来
	file, err := os.Open(text)
	//02.	读文件
	if err != nil {
		panic(err)
	}
	//03.	读文件
	FileInfo, err2 := file.Stat() //stat函数 返回( fileinfo, err)
	if err2 != nil {
		panic(err2)
	}
	//04.	buffer  对接要读取的数据
	buffer := make([]byte, FileInfo.Size())
	//
	n, err3 := file.Read(buffer)
	if err3 != nil {
		panic(err3)
	}
	defer file.Close()
	//
	fmt.Println("--------------------", n)
	//05.	从数据中查找到下一个pem格式的块
	block, _ := pem.Decode(buffer)
	if block == nil {
		return nil
	}
	//06.	解析一个der编码的私钥
	pubInterface, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil
	}
	//07.	私钥解密
	result, _ := rsa.DecryptPKCS1v15(rand.Reader, pubInterface, []byte(text))
	//08.	返回私钥后的数据
	return result
}
  • 重要函数:
  1. 将得到的Pem格式私钥通过文件指针写入磁盘中
    "encoding/pem" 包中的函数
    func Decode(data []byte) (p *Block, rest []byte)
        - 参数 data: 需要解析的数据块
        - 返回值1: 从参数中解析出的PEM格式的块
        - 返回值2: 参数data剩余的未被解码的数据

     

  2. 解析一个DER编码的公钥 , pem中的Block结构体中的数据格式为ASN.1编码
    函数所属的包: "crypto/x509"
    func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)
        - 参数 derBytes: 从pem的Block结构体中取的ASN.1编码数据
        - 返回值 pub: 接口对象, 实际是公钥数据
        - 参数 err:   错误信息

     

  3. 解析一个DER编码的私钥 , pem中的Block结构体中的数据格式为ASN.1编码
    函数所属的包: "crypto/x509"
    func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error)
        - 参数 der: 从pem的Block结构体中取的ASN.1编码数据
        - 返回值 key: 解析出的私钥
        - 返回值 err: 错误信息

     

  4. 将接口转换为公钥
    pubKey := pubInterface.(*rsa.PublicKey)
        - pubInterface: ParsePKIXPublicKey函数返回的 interface{} 对象
        - pubInterface.(*rsa.PublicKey): 将pubInterface转换为公钥类型 rsa.PublicKey

     

  5. 使用公钥加密数据
    函数所属的包: "crypto/rsa"
    func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error)
        - 参数 rand: 随机数生成器, 赋值为 rand.Reader
        - 参数 pub:  非对称加密加密使用的公钥
        - 参数 msg:  要使用公钥加密的原始数据
        - 返回值 out: 加密之后的数据
        - 返回值 err: 错误信息

     

  6. 使用私钥解密数据
    函数所属的包: "crypto/rsa"
    func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error)
        - 参数 rand: 随机数生成器, 赋值为 rand.Reader
        - 参数 priv: 非对称加密解密使用的私钥
        - 参数 ciphertext: 需要使用私钥解密的数据
        - 返回值 out: 解密之后得到的数据
        - 返回值 err: 错误信

     

我想我更懂了.....

相关文章: