看了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 error var prk *ecdsa.PrivateKey
var puk ecdsa.PublicKey
var curve elliptic.Curve
curve = elliptic.P256() //func NewReader(s string) *Reader
prk, err = ecdsa.GenerateKey(curve,rand.Reader)
if err != nil {
return prk, puk, err
}
//prk:私钥 puk:公钥
puk = prk.PublicKey return 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。写入返回值的数据都会在压缩后写入w
w := 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)
}

go加密算法:非对称加密(三)--Elliptic的更多相关文章

  1. go加密算法:非对称加密(一)--RSA

    椭圆曲线加密__http://blog.51cto.com/11821908/2057726 // MyRas.go package main import ( "crypto/rand&q ...

  2. go加密算法:非对称加密(二)--Hash

    关于一些加密算法的应用和信息,可以在以下博客中查找到: https://www.cnblogs.com/charlesblc/p/6130141.html // MyHash package main ...

  3. 非对称加密RSA的C#实现

    1.对称加密算法 对称加密是最快速.最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key). 对称加密有很多种算法,由于它效率很高,所 ...

  4. openssl 下的对称加密和非对称加密

    对称加密: 在加密和解密过程中使用相同的密钥, 或是两个可以简单地相互推算的密钥的加密算法. 非对称加密: 也称为公开加密, 它需要一个密钥对, 一个是公钥, 一个是私钥, 一个负责加密, 一个负责解 ...

  5. 非对称加密RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。使用最广泛的是RSA算法

          非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey).公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密:如果用私 ...

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

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

  7. 加密算法之非对称加密RSA

    一:非对称加密的由来 RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有 ...

  8. 常见三种加密(MD5、非对称加密,对称加密)

    转载. https://blog.csdn.net/SSY_1992/article/details/79094556 任何应用的开发中安全都是重中之重,在信息交互异常活跃的现在,信息加密技术显得尤为 ...

  9. Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA

    版权声明:本文为博主原创文章,未经博主允许不得转载. [前言] 本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及使用方法和例子 [最简单的加密] 1.简单的概念 明文:加密前的 ...

随机推荐

  1. 【Python】面向对象编程思想

    概念 "笔"作为一个抽象的概念,可以被看成是一个类.而一支实实在在的笔,则是"笔"这种类型的对象. 一个类可以有属于它的函数,这种函数被称为类的"方法 ...

  2. java面试题----IO流种类及接口方法

    java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种 ...

  3. golang闭包

    http://blog.51cto.com/speakingbaicai/1703229 https://www.jianshu.com/p/fa21e6fada70 所谓闭包就是一个函数" ...

  4. 两个知识点的回顾(const指针和动态链接库函数dlopen)

    昨天,看了一点<c++ primer>和<程序员的自我修养>,想起了自己以前的两个知识点,这里回顾,并且总结一下. 1. const指针的参数 看primer的时候,看到几个概 ...

  5. shell脚本需求

    需求一:写一个脚本 1.设定变量FILE的值为/etc/passwd 2.依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么 形如:(提示:LINE=`wc -l /etc/pas ...

  6. 稳定sqlplan方法

    参考文档:SQLT (SQLTXPLAIN) - Tool that helps to diagnose SQL statements performing poorly [ID 215187.1]

  7. June 27th 2017 Week 26th Tuesday

    Happiness takes no account of time. 幸福不觉光阴过. At the beginning of this week, I planned to make some s ...

  8. ZT 设计模式六大原则(6):开闭原则

    ZT 设计模式六大原则(6):开闭原则 分类: 设计模式 2012-02-27 08:48 24870人阅读 评论(72) 收藏 举报 设计模式扩展框架编程测试 定义:一个软件实体如类.模块和函数应该 ...

  9. 服务容错处理库Polly使用

    服务容错处理库Polly使用 在进入SOA之后,我们的代码从本地方法调用变成了跨机器的通信.任何一个新技术的引入都会为我们解决特定的问题,都会带来一些新的问题.比如网络故障.依赖服务崩溃.超时.服务器 ...

  10. Django 创建模型 激活模型 简单的使用模型

    创建模型: 在你的开发环境中,已经有一个“项目” —— 已经建立起来,你将开始在上面做一些东西. 你编写的每个Django应用都是一个遵循特定约定的Python包. Django自带一个工具,它可以自 ...