首页 > 其他分享 >RSA 笔记总结

RSA 笔记总结

时间:2023-02-07 18:46:49浏览次数:36  
标签:总结 公钥 私钥 err nil RSA 笔记 加密 block

一、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的私钥加签名,即 先加密后签名 达到既不泄露也不被篡改,更能保证消息的安全性。

  总结:公钥加密、私钥解密、私钥签名、公钥验签。

 
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
}

  

标签:总结,公钥,私钥,err,nil,RSA,笔记,加密,block
From: https://www.cnblogs.com/Sunbreaker/p/17099457.html

相关文章

  • 《Vue.js 设计与实现》读书笔记 - 第13章、异步组件与函数式组件
    第13章、异步组件与函数式组件13.1异步组件要解决的问题用户可以简单通过import异步导入组件。<template><component:is="asyncComp"></template><script>ex......
  • SIP协议学习笔记
    友情提示:初次接触SIP(SessionInitiationProtocol)协议的同学,强烈建议先将文末参考文章中的链接,先看至少二遍! 一、SIP协议是一个文本协议言外之意:不同于二进制难以阅......
  • freeswitch笔记(9)-esl outbound中如何放音采集按键?
    关于这个功能,esl-client上给出的源码示例极具误导性,根本跑不起来,见: https://github.com/esl-client/esl-client/blob/master/src/test/java/OutboundTest.java 正确姿......
  • freeswitch笔记(8)-esl outbound 填坑笔记
    github上的esl-client已经N年未更新了,上面有一堆bug,记录一下: 一、内存泄露org.freeswitch.esl.client.transport.message.EslFrameDecoder这个类,使用了netty的ByteBuf......
  • freeswitch笔记(7)-放音控制
    来电时,播放音乐是一个很常用的功能,下面是一些相关的命令:一、单次播放playback1originateuser/1000 &playback(ivr/8000/ivr-welcome_to_freeswitch.wav)......
  • freeswitch笔记(6)-会议功能简介
    电话会议是一个常用功能,freeswitch当然支持,下面是基本用法:一、发起会议1conference test bgdialuser/1004上面的命令表示,发起1个名为test的会话,......
  • freeswitch笔记(5)-小型呼叫中心设计思路
    这一篇用esl实战一把,利用eslclient来实现一个小型呼叫中心的原型,先看看下面这张图: 企业通常会对外公布一个400之类的服务电话,当用户拨打这个电话时,实际上背后是一堆客......
  • freeswitch笔记(4)-esl inbound模式的重连及内存泄露问题
    eslinboundclient,内部有一个canSend()方法:123publicbooleancanSend(){    return channel!=null&&channel.isConnected()&&authenticated......
  • java_html笔记
    颜色color字体大小 1.数值+单位 2.关键字-px-em字体(可以写多个,但不是全都生效只生效存在的如果全都不存在则使用默认字体)font-family:"abccde",......
  • python笔记1
    1.python转义符\"输出等于“\n换行\r覆盖,后面覆盖前面 \b删除前面一个字节\t制表符:插入四个空格,但是会自动补齐\\两个斜杠表示一个斜杠r在前面写个r表示转义字符......