文章目录

  • 一、相关知识扫盲篇
    • 数字签名、数字证书
    • 防止证书伪造 之 证书链-Digital Certificates
  • 二、公私钥格式、协议规范
  • 三、golang RSA加密、解密具体实现
    • `RSA`加密、解密
      • `RSA`公钥加密
      • `RSA`私钥解密
      • `hmac_sha256`加密
      • 私钥加密,生成签名`SHA256withRSA`
      • `RSA`公钥验证签名
    • golang解析数字证书操作

一、相关知识扫盲篇

数字签名、数字证书

A与B的交互,通过一方的公私密钥,实现数据的加密,解密,验证数据签名,以保证其数据是对的。

但是存在比如B处存放的A的公钥被别人替换为如C的公钥可能性,这样C去发送信息给B,B会误以为是A发的,达到欺骗的效果
由此出现了,中心证书的CA(Certificate authority)机构,做中间人,把公钥持有人的信息,再用机构的私钥对A的信息进行加密。

B拿到数据,先用证书持有机构的公钥进行解密,证明是A的数据,然后再用A的公钥进行验签

引申:既然道格可以替换鲍勃的公钥,为什么不能故技重施,伪造CA的公钥,然后用自己的私钥伪造成CA的数字证书,从而达到欺骗苏珊的目的呢?

解释:CA的公钥是公开的,是可查的,他们的公钥在自己网站上提供下载,因此无法伪造

总结:公私钥用于加密、验证之间的数据,证书(中心媒介)用于证明其拿到的是正确的交互方的公钥。

防止证书伪造 之 证书链-Digital Certificates

文档地址,点击跳转

SHA256withRSA 先用RAS加密,在执行SHA256的哈希运算,主要用在签名验证操作

二、公私钥格式、协议规范

  • 公私钥格式、标准、规范,golang生成公私钥,见(https://blog.csdn.net/BuquTianya/article/details/82958194)
  • openssl数字证书常见格式与协议介绍

主要涉及的go包:

  • x509 x509包解析X.509(密码学里公钥证书的格式标准)编码的证书和密钥
  • pem包,pem包实现了PEM数据编码(源自保密增强邮件协议 Privacy Enbanced Mail)。目前PEM编码主要用于TLS密钥和证书
  • crypto/rsa rsa包实现了PKCS#1规定的RSA加密算法

三、golang RSA加密、解密具体实现

RSA加密、解密

  • RSA加密数据
  • 再配合 SHA256哈希 获得不可修改的签名signature

RSA公钥加密

// 公钥加密-分段func RsaEncryptBlock(src, publicKeyByte []byte) (bytesEncrypt []byte, err error) {// 解码公钥文件,返回block结构// The encoded form is://    -----BEGIN Type-----//    Headers//    base64-encoded Bytes//    -----END Type-----block, _ := pem.Decode(publicKeyByte)if block == nil {return nil, errors.New("Decode PublicKey Fail")}// 解析 PKIX 格式的公钥,返回 *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey 等格式的structpublicKey, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {return nil, err}//根据自己具体使用的格式做推测pub, keySize :=  publicKey.(*rsa.PublicKey), publicKey.(*rsa.PublicKey).Size()srcSize := len(src)fmt.Println("密钥长度:", keySize, "\t明文长度:\t", srcSize)//单次加密的长度需要减掉padding的长度,PKCS1为11// 按需加密offSet, once := 0, keySize-11buffer := bytes.Buffer{}for offSet < srcSize {endIndex := offSet + onceif endIndex > srcSize {endIndex = srcSize}// 加密一部分bytesOnce, err := rsa.EncryptPKCS1v15(myrand.Reader, pub, src[offSet:endIndex])if err != nil {return nil, err}buffer.Write(bytesOnce)offSet = endIndex}bytesEncrypt = buffer.Bytes()return
}

RSA私钥解密

**
私钥解密-分段*/
func RsaDecryptBlock(src, privateKeyByte []byte) (bytesDecrypt  []byte, err error) {block, _ := pem.Decode(privateKeyByte)if block == nil {return nil, errors.New("Decode PrivateKey Fail")}// 注意格式 PKCS8 / PKCS1privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)if err != nil {return nil, err}private := privateKey.(*rsa.PrivateKey)keySize, srcSize := private.Size(), len(src)fmt.Println("密钥长度:", keySize, "\t密文长度:\t", srcSize)var offSet = 0var buffer = bytes.Buffer{}for offSet < srcSize {endIndex := offSet + keySizeif endIndex > srcSize {endIndex = srcSize}// 解密bytesOnce, err := rsa.DecryptPKCS1v15(myrand.Reader, private, src[offSet:endIndex])if err != nil {return nil, err}buffer.Write(bytesOnce)offSet = endIndex}bytesDecrypt = buffer.Bytes()return
}

hmac_sha256加密

func HmacSha256(message string, secret string) string {key := []byte(secret)h := hmac.New(sha256.New, key)h.Write([]byte(message))return base64.StdEncoding.EncodeToString(h.Sum(nil))  // 转base64str
}

私钥加密,生成签名SHA256withRSA

func RSASign(origData string, privateKeyBytes []byte) (sign string,err error) {/*// 可以通过读取私钥文件,获取私钥字节数据privateKeyBytes, err := ioutil.ReadFile(filename)if err != nil {return nil, err}*/// 解码私钥blocks,_  := pem.Decode(privateKeyBytes)if block == nil {return nil, errors.New("decode privatekey fail")}// 解析私钥对象privateKey, _ := x509.ParsePKCS8PrivateKey(blocks.Bytes)// 选择hash算法,对数据进行hashh := sha256.New()h.Write([]byte(origData))digest := h.Sum(nil)// 生成签名s, _ := rsa.SignPKCS1v15(nil, privateKey.(*rsa.PrivateKey), crypto.SHA256, digest)// 获取base64strsign = base64.StdEncoding.EncodeToString(s)return sign, nil
}

RSA公钥验证签名

func RSAVerify(data []byte, base64Sig, filename string) error {// 对base64编码的签名内容进行解码sign_bytes, err := base64.StdEncoding.DecodeString(base64Sig)if err != nil {return err}// 选择hash算法,对需要签名的数据进行hash运算myhash := crypto.SHA256hashInstance := myhash.New()hashInstance.Write(data)hashed := hashInstance.Sum(nil)// 读取公钥文件,解析出公钥对象// 1、读取公钥文件,获取公钥字节publicKeyBytes, err := ioutil.ReadFile(filename)if err != nil {return err}// 2、解码公钥字节,生成加密对象block, _ := pem.Decode(publicKeyBytes)if block == nil {return errors.New("decode publicKey fail")}// 3、解析DER编码的公钥,生成公钥接口publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {return err}// 4、公钥接口转型成公钥对象(按需转换判断类型)publicKey := publicKeyInterface.(*rsa.PublicKey)// RSA验证数字签名(参数是公钥对象、哈希类型、签名文件的哈希串、已知的签名数据)return rsa.VerifyPKCS1v15(publicKey, myhash, hashed, sign_bytes)
}

这里以PayPal webhook数据验签(SHA256withRSA)举例:

import ("crypto""crypto/rsa""crypto/x509""encoding/base64""encoding/pem""errors""github.com/astaxie/beego/logs""hash/crc32""io/ioutil""net/http""strconv"
)type PayPalWebHook struct {TransmissionID   string // Paypal-Transmission-IdTransmissionTime string // Paypal-Transmission-Time (请求头header里边)TransmissionSig  string // Paypal-Transmission-Sig 传递来的签名WebHookID        string // webhook_id 注意与  webhook_event_id做区分CertUrl          string // Paypal-Cert-UrlEventData        []byte // payload data
}func (this *PayPalWebHook) VerifySignature() (bool, error) {//获取证书 // 这里使用下载证书的方式,如果是本地使用io操作读取即可resp, err := http.Get(this.CertUrl)if err != nil {logs.Error("[Get Cert Error]: ", err)return false, err}defer resp.Body.Close()cert_bytes, err := ioutil.ReadAll(resp.Body)if err != nil {return false, err}//解析pub_key,从证书里边解析出公钥// 若已有公钥,则忽略此从证书解出公钥的操作pub_key, err := this.getPublicKey(cert_bytes)if err != nil {return false, err}//拼接签名所需字符串。expect_str := this.getExpectedStr()//执行校验sig_bytes, err := base64.StdEncoding.DecodeString(this.TransmissionSig)if err != nil {logs.Error("[base64 decode error]: ", err)return false, err}hash_handler := crypto.SHA256hash_instance := hash_handler.New()hash_instance.Write([]byte(expect_str))hashed := hash_instance.Sum(nil)err = rsa.VerifyPKCS1v15(pub_key, hash_handler, hashed, sig_bytes)if err != nil {logs.Error("[Verify Signature Error]: ", err)return false, err}return true, nil
}//获取签名拼接字符串(按需设置)
func (this *PayPalWebHook) getExpectedStr() string {// 这里取数据的crc32冗余校验的值,和相关参数做拼接的hash前的数据字符串。按需改为需要进行签名操作的数据//crc冗余校验event_crc32 := crc32.ChecksumIEEE(this.EventData)//PayPal签名要求格式expect_string := this.TransmissionID + "|" + this.TransmissionTime + "|" + this.WebHookID + "|" + strconv.FormatUint(uint64(event_crc32), 10)logs.Debug("[Expect string]: ", expect_string)return expect_string
}// 从证书里提取公钥
func (this *PayPalWebHook) getPublicKey(cert_bytes []byte) (*rsa.PublicKey, error) {//解码证书pem,验证格式cert_der_block, _ := pem.Decode(cert_bytes)if cert_der_block == nil {logs.Error(cert_der_block)return nil, errors.New("decode_cert_error")}//解析证书cert, err := x509.ParseCertificate(cert_der_block.Bytes)if err != nil {logs.Error("[ParseCertificate Error]: , err")return nil, err}//序列化公钥pub_key_der, err := x509.MarshalPKIXPublicKey(cert.PublicKey)if err != nil {logs.Error("[MarshalPKIXPublicKey Error]: ", err)return nil, err}//解析公钥pub_key, err := x509.ParsePKIXPublicKey(pub_key_der)if err != nil {logs.Error("[ParsePKIXPublicKey Error]: ", err)return nil, err}//这里因为知道其加密方式,直接推断的rsa,这里根据具体情况修改实现return pub_key.(*rsa.PublicKey), nil
}

golang解析数字证书操作

  • golang解析数字证书和PKCS#1&PKCS#8格式的私钥

数字签名、证书,RSA加密、解密相关推荐

  1. RSA加密解密及数字签名Java实现--转

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院 ...

  2. python rsa加密解密_RSA加密解密(python版)

    RSA的算法涉及三个参数,n.e.d. 其中,n是两个大质数p.q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度. e1和d是一对相关的值,e可以任意取,但要求e与(p-1)*(q-1)互质: ...

  3. 可以考的python方面的证书-python有证书的加密解密实现方法

    本文实例讲述了python有证书的加密解密实现方法.分享给大家供大家参考.具体实现方法如下: 最近在做python的加解密工作,同时加完密的串能在php上能解出来,网上也找了一些靠谱的资料,刚好也有时 ...

  4. [crypto]-53-openssl命令行的使用(aes/rsa签名校验/rsa加密解密/hmac)

    常用技巧 如何编写一个二进制规律性的文件, 比如你可以编写一个"0123456789abcdef"的文本文件,记得删除换行符然后用ultraedit打开,ctrl+H就可以看到二进 ...

  5. RSA加密解密和签名的应用场景

    由 RSA 可以生成一对密钥(私钥和公钥) 明文消息用公钥进行加密后,可以得到密文消息. 密文消息必须用私钥进行解密后,才能得到明文消息. 公钥是公布出去的,任何人都可以知道. 密钥自己藏着,只有自己 ...

  6. Linux的rsa命令,openssl命令行进行RSA加密解密

    openssl是一个功能强大的工具包,它集成了众多密码算法及实用工具.我们即可以利用它提供的命令台工具生成密钥.证书来加密解密文件,也可以在利用其提供的API接口在代码中对传输信息进行加密. RSA是 ...

  7. IOS之RSA加密解密与后台之间的双向加密详解

    IOS之RSA加密解密与后台之间的双向加密详解 序言 因为项目中需要用到RSA加密,刚开始也是有点乱,这两天也整理的差不多了,希望能帮到大家. 这次先上代码,我想大部分人肯定是着急解决问题,所以不要废 ...

  8. Crypto++安装和简单使用RSA加密解密

    Crypto++安装和简单使用 一.前言 二.下载 三.安装 四.使用 五.RSA加密/解密 (一)生成密钥/公钥 (二)OAEP加密/解密 六.RSA加密/解密的源码 一.前言 能搜索这个的估计都知 ...

  9. iOS使用Security.framework进行RSA 加密解密签名和验证签名

    iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...

  10. ios php rsa加密解密,php rsa加密解密使用详解

    第一条命令生成原始 RSA私钥文件 rsa_private_key.pem,第二条命令将原始 RSA私钥转换为 pkcs8格式,第三条生成RSA公钥 rsa_public_key.pem 从上面看出通 ...

最新文章

  1. 计算机报名显示事务已被锁死,ORA-01591错误处理: 锁定已被有问题的分配事务处理20.18.156406挂起(转载)...
  2. linux安装后启动mysql,linux安装完mysql后启动错误
  3. 今天的成功的滋味 企业即时通讯
  4. 信息学奥赛一本通 1345:【例4-6】香甜的黄油 | 洛谷 P1828 [USACO3.2]香甜的黄油 Sweet Butter
  5. fortran 读整行_我整周读过的最有趣的东西
  6. Java新特性之Nashorn的实例详解
  7. vb连接mysql数据库报错_vb6连接mysql数据库
  8. ask调制流程图_bpsk调制原理
  9. VUE下载安装与配置
  10. 产品经理的自我修养:认知模式
  11. “TOP面对面” 技术AMA系列第一期:揭开TOP技术团队的神秘面纱
  12. py读取xlsx文件
  13. OpenCV——图像连通域
  14. git init和git clone获取仓库 (一)
  15. python入侵手机_Python-Iocextract:高级入侵威胁标识符IoC提取工具
  16. IT职场法则七条——献给正在努力奋斗的你们
  17. 云计算平台建设总体技术方案
  18. SAP BAdI 深度解读
  19. 逆战小白提升日記——网红时钟罗盘北京时间页代码
  20. 文件操作模式 r+ w+ a+ 文件读写模式的区别

热门文章

  1. Python pip/pip3 常用命令
  2. 数据挖掘之关联规则挖掘的一些定义
  3. floodFill详解
  4. 《算法竞赛入门经典(第二版)》pdf
  5. 二叉树先序遍历、中序遍历、后序遍历 递归和非递归算法
  6. Python 爬取网页
  7. PC端微信多开bat命令
  8. loadrunner录制网页脚本时打不开或打开慢
  9. 【Hbase】HBase入门教程
  10. android 语音适配,Android多语言适配繁体中文