看了2星期的区块链原理与运行机制,加密这里开始变得有些生疏,花了一天时间复习了一些;看到了之前忽略的,也学会了椭圆曲线加密。

//基础板:浅显易懂package main

import (   "crypto/ecdsa"   "crypto/md5"   "encoding/hex"   "fmt"   "math/big"   "strings"

   "crypto/elliptic"   "crypto/rand")

func main() {   src := []byte(string("少壮不努力,活该你单身23333"))   //src1 := []byte(string("少壮不努力,老大徒伤悲3344"))   mysrc := myHash(src)   //mysrc1 := myHash(src1)

   prk, puk, _ := genePriPubKey()   mystring := sign(prk, mysrc)

   r, s := getSign(mystring)

   result := verifySign(&r, &s, mysrc, puk)   fmt.Print(result)

}

func genePriPubKey() (*ecdsa.PrivateKey, ecdsa.PublicKey, error) {

   var err error   var pubkey ecdsa.PublicKey   var prikey *ecdsa.PrivateKey   var curve elliptic.Curve

   curve = elliptic.P384()   prikey, err = ecdsa.GenerateKey(curve, rand.Reader)   if err != nil {      return prikey, pubkey, err   }   pubkey = prikey.PublicKey

   return prikey, pubkey, err}func myHash(src []byte) []byte {   myhash := md5.New()   myhash.Write(src)   return myhash.Sum(nil)}

func sign(key *ecdsa.PrivateKey, myhash []byte) string {   r, s, _ := ecdsa.Sign(rand.Reader, key, myhash)   rm, _ := r.MarshalText()   sm, _ := s.MarshalText()

   return hex.EncodeToString([]byte(string(rm) + "+" + string(sm)))}

func getSign(hexrs string) (rint, sint big.Int) {   st, _ := hex.DecodeString(hexrs)   str := strings.Split(string(st), "+")   _ = rint.UnmarshalText([]byte(str[0]))   //rint是指针:error: invalid memory address or nil pointer dereference   _ = sint.UnmarshalText([]byte(str[1]))

   return}

func verifySign(rint, sint *big.Int, myhash []byte, pubkey ecdsa.PublicKey) bool {   result := ecdsa.Verify(&pubkey, myhash, rint, sint)   return result}

//进阶版:结合gzip/bytes的使用,加入缓冲
package main//https://studygolang.com/articles/13228
//https://blog.csdn.net/teaspring/article/details/77834360
import ("bytes""compress/gzip"//实现了gzip格式压缩文件的读写"crypto/ecdsa""crypto/elliptic""crypto/md5""crypto/rand""encoding/hex"//实现了16进制字符表示的编解码"errors""fmt""math/big"//实现了大数字的多精度计算"strings"
)
/*
io包提供了对I/O原语的基本接口。本包的基本任务是包装这些原语已有的实现(如os包里的原语),
使之成为共享的公共接口,这些公共接口抽象出了泛用的函数并附加了一些相关的原语的操作
*/
/**通过一个随机key创建公钥和私钥随机key至少为36位
*/func getEcdsaKey() (*ecdsa.PrivateKey, ecdsa.PublicKey, error) {var err errorvar prk *ecdsa.PrivateKeyvar puk ecdsa.PublicKeyvar curve elliptic.Curvecurve = elliptic.P256()//func NewReader(s string) *Readerprk, err = ecdsa.GenerateKey(curve,rand.Reader)if err != nil {return prk, puk, err}//prk:私钥 puk:公钥puk = prk.PublicKeyreturn prk, puk, err}/**对text加密,text必须是一个hash值,例如md5、sha1等使用私钥prk返回加密结果,结果为数字证书r、s的序列化后拼接,然后用hex转换为string
*/
func sign(text []byte, prk *ecdsa.PrivateKey) (string, error) {//r, s, err := ecdsa.Sign(strings.NewReader(randSign), prk, text)r, s, err := ecdsa.Sign(rand.Reader, prk, text)if err != nil {return "", err}rt, err := r.MarshalText()if err != nil {return "", err}st, err := s.MarshalText()if err != nil {return "", err}var b bytes.Buffer//创建并返回一个Writer。写入返回值的数据都会在压缩后写入ww := gzip.NewWriter(&b)//内建函数close关闭信道,该通道必须为双向的或只发送的//defer通常用来释放函数内部变量。defer w.Close()_, err = w.Write([]byte(string(rt) + "+" + string(st)))if err != nil {return "", err}w.Flush()//确保所有的缓存操作已写入底层写入器return hex.EncodeToString(b.Bytes()), nil
}/**证书分解通过hex解码,分割成数字证书r,s
*/
func getSign(signature string) (rint, sint big.Int, err error) {byterun, err := hex.DecodeString(signature)if err != nil {err = errors.New("decrypt error, " + err.Error())return}/*gzip.NewReader(r io.Reader) (*Reader, error)返回一个从r读取并解压数据的*Reader。其实现会缓冲输入流的数据,并可能从r中读取比需要的更多的数据。调用者有责任在读取完毕后调用返回值的Close方法。buffer.NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }使用buf作为初始内容创建并初始化一个Buffer。本函数用于创建一个用于读取已存在数据的buffer;也用于指定用于写入的内部缓冲的大小,此时,buf应为一个具有指定容量但长度为0的切片。buf会被作为返回值的底层缓冲切片。大多数情况下,new(Buffer)(或只是声明一个Buffer类型变量)就足以初始化一个Buffer了。*///Buffer是一个实现了读写方法的可变大小的字节缓冲r, err := gzip.NewReader(bytes.NewBuffer(byterun))if err != nil {err = errors.New("decode error," + err.Error())return}defer r.Close()buf := make([]byte, 1024)//Reader类型满足io.Reader接口,可以从gzip格式压缩文件读取并解压数据。//一般,一个gzip文件可以是多个gzip文件的串联,每一个都有自己的头域。从Reader读取数据会返回串联的每个文件的解压数据,// 但只有第一个文件的头域被记录在Reader的Header字段里。//gzip文件会保存未压缩数据的长度与校验和。当读取到未压缩数据的结尾时,如果数据的长度或者校验和不正确,//Reader会返回ErrCheckSum。因此,调用者应该将Read方法返回的数据视为暂定的,直到他们在数据结尾获得了一个io.EOF。count, err := r.Read(buf)//func (z *Reader) Read(p []byte) (n int, err error)if err != nil {fmt.Println("decode = ", err)err = errors.New("decode read error," + err.Error())return}//Split(s, sep string) []string //sep:步长rs := strings.Split(string(buf[:count]), "+")if len(rs) != 2 {err = errors.New("decode fail")return}//实现了Marshaler接口的类型可以将自身序列化为合法的json描述。//UnmarshalText必须可以解码MarshalText生成的textual格式数据。//本函数可能会对data内容作出修改,所以如果要保持data的数据请事先进行拷贝err = rint.UnmarshalText([]byte(rs[0]))if err != nil {err = errors.New("decrypt rint fail, " + err.Error())return}err = sint.UnmarshalText([]byte(rs[1]))if err != nil {err = errors.New("decrypt sint fail, " + err.Error())return}return}/**校验文本内容是否与签名一致使用公钥校验签名和文本内容
*/
func verify(text []byte, signature string, key ecdsa.PublicKey) (bool, error) {rint, sint, err := getSign(signature)if err != nil {return false, err}result := ecdsa.Verify(&key, text, &rint, &sint)return result, nil
}/**hash加密使用md5加密msg+
*/
//func hashtext(text, salt string) []byte {
func hashtext(text  string) []byte {Md5Inst := md5.New()Md5Inst.Write([]byte(text))//result := Md5Inst.Sum([]byte(salt))return Md5Inst.Sum(nil)
}func main() {//创建公钥和私钥prk, puk, err := getEcdsaKey()if err != nil {fmt.Println(err)}//待加密的明文text := string("少壮不努力,活该你单身2333")//hash取值htext := hashtext(text)//hash值编码输出hex.EncodeToString(htext)//hash值+私钥进行签名result, err := sign(htext, prk)if err != nil {fmt.Println(err)}//签名与hash值进行校验//hash值+密文+公钥tmp, err := verify(htext, result, puk)fmt.Println(tmp)
}

转载于:https://www.cnblogs.com/eilinge/p/10225079.html

go加密算法:非对称加密(三)--Elliptic相关推荐

  1. 各种Java加密算法-非对称加密

    RSA      这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作,也很流行.算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和 ...

  2. Java加密算法—非对称加密

    目录 1.概述 2.对称加密.解密实现 1.概述 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey) 和私有密钥(privatekey),公开密钥和私有密钥是一对,如果用公 ...

  3. 【加密】对称加密DES和非对称加密AES、数字签名|非对称加密--公钥和私钥的区别

    目录 对称加密DES和非对称加密AES.数字签名 对称加密 1.1 定义 1.2 优缺点 1.3 常用对称加密算法 非对称加密( Asymmetric Cryptography ) 非对称加密(现代加 ...

  4. 【Kotlin学习之旅】使用Kotlin实现常见的对称加密、非对称加密、消息摘要、数字签名的demo

    文章目录 Demo 介绍 一.对称加密 二.非对称加密 三.消息摘要 四.数字签名 五.Demo地址 Demo 介绍 使用Kotlin实现常见的对称加密.非对称加密.消息摘要.数字签名的demo 一. ...

  5. 十七.SpringCloud+Security+Oauth2实现微服务授权 -非对称加密生成JWT令牌

    仅做学习使用,老鸟飞过,欢迎交流 前言 在之前的微服务授权方案<SpringCloud+Security+Oauth2实现微服务授权 - 授权服务配置>中我们使用的是Oauth+JWT方式 ...

  6. 对称加密非对称加密怎么一起使用(初级版)

    对称加密 加密和解密使用相同的密钥,使用一把钥匙,所以叫对称加密,对称 加密包括多种算法,如:DES,3DES,AES 加密长度一般小于256位,防止数据被泄. 优点:加密和解密的速度快.缺点:因为使 ...

  7. Java加密与解密笔记(三) 非对称加密

    非对称的特点是加密和解密时使用的是不同的钥匙.密钥分为公钥和私钥,用公钥加密的数据只能用私钥进行解密,反之亦然. 另外,密钥还可以用于数字签名.数字签名跟上文说的消息摘要是一个道理,通过一定方法对数据 ...

  8. 非对称加密算法 - Java加密与安全

    非对称加密算法我们从DH算法中可以看到密钥对是一种非常有用的加密算法 密钥对中publicKey是可以公开的,而privateKey则是需要保密的,由此奠定了非对称加密的基础 非对称加密就是加密和解密 ...

  9. 非对称加密 公钥私钥_选择Java加密算法第3部分–公钥/私钥非对称加密

    非对称加密 公钥私钥 抽象 这是涵盖Java加密算法的三部分博客系列的第3部分. 该系列涵盖如何实现以下功能: 使用SHA–512散列 使用AES–256的单密钥对称加密 RSA–4096 这第三篇文 ...

最新文章

  1. Struts2 随笔1
  2. 使用 SQLServer On Linux 作为开发数据库遇到的编码问题
  3. 安娜·塞克泽沃斯卡的“小人物”
  4. 前端学习(568):元素定高 容器定高 为什么不能居中
  5. Nutanix,在转型的道路上越走越远 | 人物志
  6. Mysql 如何通过binlog日志恢复数据
  7. Docker安装实践Jenkins
  8. Update与JOIN使用
  9. java序列化(Serializable)
  10. ajax简单异步图片上传,Ajax简单异步上传图片并回显
  11. IC基础知识7-数据选择器
  12. java连接Oracle乱码_如何解决Java连接数据库oracle中文乱码问题
  13. WINCE环境下 helloWorld
  14. win10右键卡顿原因_右键菜单反应慢?win10系统解决右键菜单卡顿方法
  15. 介绍几个免费的英文ASP.NET的CMS程序
  16. 如何查看网页元素的名称ID和其他信息
  17. 电气AutoCAD基础教学(一)——入门技巧
  18. ERC20接口下USDT代币的深入解析
  19. num_workers
  20. java实验2总结心得,打字小游戏JAVA实验总结及心得体会

热门文章

  1. Kindle支持文档类型
  2. CSDN-markdown语法之如何插入图片
  3. Java里format什么意思_java String.Format详解
  4. 老罗(www.luocong.com)
  5. svg图放大、缩小、拖拽
  6. Mac如何做才能彻底清理垃圾
  7. 通信达股票数据格式读取程序
  8. 除了迅雷,这几款下载神器也超级好用!
  9. centos7:在linux世界里,一切皆文件
  10. 即刻报名|飞桨黑客马拉松第三期盛夏登场,等你挑战