看了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. 删除List中指定的元素

    删除List中指定的元素 CopyOnWriteArrayList是ArrayList的一个线程安全的变体实现,即可在多线程并发环境中使用 List<Map<String, Object& ...

  2. html 颜色在线取色器

    推荐一个链接 还不错 http://www.atool.org/colorpicker.php

  3. 四、CentOS 安装mariadb——Linux学习笔记

    A)安装及配置 下载mariadb: yum -y install mariadb-server mariadb 开启mariadb服务: systemctl start mariadb.servic ...

  4. simotion连接 V90 1FL6 增量型电机,报警20025 编码器细分设置

    V90 1FL6 增量型电机 The configured fine resolution for Gx_XIST1 (Encoder_N.absEncoder.absResolutionMultip ...

  5. Windows 10 X64 ISO 专业版&家庭版下载与永久激活

    好久没有更新博客,算算时间,已经有4年了,好吧,今天突发奇想,想把今天安装Windows 10的过程给记录下来. 2015年的时候,微软就发布了Windows 10,当时正版的Win7.Win8都可以 ...

  6. July 23rd 2017 Week 30th Sunday

    Setting goals is the first step in turning the invisible into the visible. 设定目标是将实现梦想的第一步. If you wa ...

  7. SNMP协议详解

    简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议.在1988年被制定,并被Internet体系结构委员会(IAB)采纳作为一个短期的网络管理解决方案:由于SNMP的简单性,在Inter ...

  8. Types of Computer Systems

    Types of Computer Systems Para 1 You should be familiar with the differences among computer systems ...

  9. hdu-2619 Love you Ten thousand years

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2619 题目大意: 求出小于n的数的个数,满足ki mod n,1≤i≤n是模n的完全剩余系 解题思路 ...

  10. Intellij IDEA 代码中类非全路径显示