想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】 链客,有问必答!!
数字签名在信息安全,包括身份认证、数据完整性、不能否认性以及匿名性有着重要应用,是现代密码学的重要分支。签名隶属于公钥密码学。签名过程:发送方用本身的私钥对发送信息进行所谓的加密运算,获得一个hash值,该hash值就是签名。使用时须要将签名和信息发给接收方。接受者用发送方公开的公钥和接收到的信息对签名进行验证,经过认证,说明接收到的信息是完整的、准确的,不然说明消息来源不对。算法
简单描述数字签名:私钥签名;公钥验签。数组
1 普通签名
签名只是用一把私钥,而且是发送方本身进行地签名动做,这类签名就是普通签名。经常使用的签名方法有较多,包括RSA数字签名、DSS数字签名、ElGamal数字签名、ECDSA数字签名等等。其中RSA和ECDSA签名已经在加密算法中有讲解。区块链项目中最经常使用的签名方法是ECDSA数字签名。签名和验签的原理不做讲解,感兴趣能够翻阅以前的章节。安全
由于ECDSA数字签名在区块链的重要性,我接下来只对它进行讲解如何应用。
下边代码展现简单地用ECDSA签名对数据BLOCK进行签名,上链以前须要先进行验证,验证经过以后才能上链。具体解析在代码中有说明。app
过程:
1.经过ecdsa.GenerateKey产生一私钥;输出的私钥是指针类型;
2.经过私钥产生公钥;
3.对数据BLOCK进行hash运算,实际公链中就是挖矿过程;
4.为了能够给任何长度的data进行签名,咱们建立本身的签名方法;
5.验证数据是否合法,也就是经过公钥对签名进行验证,经过后才能对数据进行上链动做。函数
package main区块链
import (加密
"bytes" "encoding/binary" "log" "time" "crypto/sha256" "fmt" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "math/big"
)代理
//简单的区块链块结构
type Block struct {指针
//1. 区块高度 Height int64 //2. 上一个区块HASH PrevBlockHash []byte //3. 交易数据 Data []byte //4. 时间戳 Timestamp int64 //5. 实际经过挖矿获得Hash Hash []byte // 6. 随机数Nonce Nonce int64
}code
func main() {
//调用底层函数,产生私钥
prk,_:=ecdsa.GenerateKey(elliptic.P256(),rand.Reader) //生成公钥 pubkey:=prk.PublicKey //须要上链的数据 data:=[]byte("helloworld") //手动建立一个区块信息,实际中,经过交易来触发自动建立block block:=&Block{2,nil,data,time.Now().Unix(),nil,0} //将block信息内容拼接成字节数组 blockbytes:=prepareData(block) //对block进行hash运算,实际中是挖矿过程 blockHash:=sha256.Sum256(blockbytes)
//签名
signatrue,_:=Sign(blockHash[:],prk)
//验证,若是经过就进行上链处理,不然rollback
if Verify(blockHash[:],signatrue,&pubkey){ fmt.Println("该block合法,能够上链") }else { fmt.Println("该Block不合法,rollback") }
}
//数据拼接
func prepareData(block *Block) []byte {
Block:=block data := bytes.Join( [][]byte{ Block.PrevBlockHash, Block.Data, IntToHex(Block.Timestamp), Block.Data, IntToHex(int64(Block.Nonce)), IntToHex(int64(Block.Height)), }, []byte{}, ) return data
}
// 将int64转换为字节数组
func IntToHex(num int64) []byte {
buff := new(bytes.Buffer) err := binary.Write(buff, binary.BigEndian, num) if err != nil { log.Panic(err) } return buff.Bytes()
}
func Sign(data []byte, privkey *ecdsa.PrivateKey) ([]byte, error) {
// 对要签名的信息进行sha256散列,生成一个长度为32的字节数组 digest := sha256.Sum256(data) // 经过椭圆曲线方法对散列后的明文进行签名,返回两个big.int类型的大数 r, s, err := ecdsa.Sign(rand.Reader, privkey, digest[:]) if err != nil { return nil, err } //将大数转换成字节数组,并拼接起来,造成签名 signature := append(r.Bytes(), s.Bytes()...) return signature, nil
}
// 经过公钥验证签名
func Verify(data, signature []byte, pubkey *ecdsa.PublicKey) bool {
// 将明文转换成字节数组 digest := sha256.Sum256(data) //声明两个大数r,s r := big.Int{} s := big.Int{} //将签名平均分割成两部分切片,并将切片转换成*big.int类型 sigLen := len(signature) r.SetBytes(signature[:(sigLen / 2)]) s.SetBytes(signature[(sigLen / 2):]) //经过公钥对获得的r,s进行验证 return ecdsa.Verify(pubkey, digest[:], &r, &s)
}
2 群签名
1991年,Chaum和Van Heyst首次提出了群签名的概念。群签名容许一个群体中的任意一个成员以匿名的方式表明整个群体对消息进行签名。
群签名须要有一个集体,通常是公司。管理员经过认证添加群签名的成员,每一个成员的签名都表明集体。利用群签名能够很好的隐藏组织结构。例如,一个公司的职员能够利用群签名方案表明公司进行签名,验证者(多是公司顾客)只须要利用公司的群公钥进行签名的合法性验证。验证者并不知道该签名是由哪一个职员所签名的。当发生争议时,群管理员能够识别出实际的签名者。固然,群签名还能够应用于电子投票、电子投标和电子现金等。
如何实现群签名呢?
入群:群成员在入群以前都会向群管理进行申请入群,经过后,申请人会和群管理员达成交互式协议,该协议可生成群成员的私钥。群管理员对该密钥进行签名,并颁发给申请人,完成入群。群成员群管理员将群公钥对外公开。
签名:群成员经过本身的群密钥和群公钥对消息进行签名,获得群签名。
验证:经过输入群公钥和群签名用公开的某种验证方法进行验证,返回值只有真假,验证者没法计算获得签名者是群公钥里的具体人员,只知道该签名者属于群公钥里的,能够表明群体。
追踪:群管理员能够经过群签名获得具体是哪一个群成员进行签名的。
群签名是一个中心化的签名结构,该结构的算法都是群管理员定的,形成签名者的隐私没有作到真正的保障。
因此总结群签名有三点:
1.只有群体中的合法成员才能表明整个群体进行签名;
2.接收者能够用群公钥验证群签名的合法性,但不知道该群签名是群体具体哪一个成员所签;、
3.在发生争议时,群管理员能够识别出实际的签名者。
3 环签名
环签名由Rivest,shamir和Tauman三位密码学家在2001年首次提出。因签名中参数Ci(i=1,2,…,n)根据必定的规则首尾相接组成环状而得名。其实就是实际的签名者用其余可能签名者的公钥产生一个带有断口的环,而后用私钥将断口连成一个完整的环。
环签名能够认为是不可追踪的群签名,实际的操做过程都是本身完成的,没有群管理员。
签名者是某个群体的成员,他把其余群体的公钥拿来并加上本身的公钥组合成一个群公钥,而后用本身的私钥和群公钥对要发布的信息进行环签名。接收者接收到群公钥、签名和信息,而后对签名进行验证,若是签名来自群公钥,那么验证成功,不然消息不合法。
群公钥中签名者的公钥只是迷惑做用,并不对数据有任何操做。
造成的签名由于是每一个其它群公钥产生的数据和本身用私钥产生的数据组成的环,本身的数据隐藏环中,攻击者很难找到签名者的公钥。因此签名者的隐私很好地被保护起来了。
4 代理签名
1996年,Mambo等人首次提出了代理签名的概念。在代理签名方案中,容许一个原始签名者把他的签名权利委托给一个称为代理签名者的人,而后代理签名者就能够表明原始签名者进行签名。代理签名者可用于须要委托权力的密码协议中,如电子现金、移动代理和移动通讯等。
5 盲签名
1982年Chaum首次提出了盲签名的概念。盲签名容许使用者得到一个消息的签名,而签名者既不知道该消息的内容,也不知道该消息的签名。盲签名可用于须要提供匿名性的密码协议中,如电子投票和电子现金。
一个盲签名方案由如下部分组成。
1)消息盲化:使用者利用盲因子对要签名的信息进行盲化处理,而后将盲化后的消息发送给签名者。
2)盲消息签名:签名者对盲化后的消息进行签名,所以他并不知道真实消息的具体内容。
3)恢复签名:使用者除去盲因子,获得真实消息的签名。
6 零知识证实零知识证实:实质上是一种涉及两方或更多方的协议,即两方或更多方完成一项任务所需采起的一系列步骤。证实者向验证者证实并使其相信本身知道或拥有某一消息,但证实过程不能向验证者泄漏任何关于被证实消息的信息。简单理解,就是证实者可以在不向验证者提供任何有用信息的状况下,让验证者相信你。