比特币(BitCoin)非对称密钥使用基本分析

栏目: 编程工具 · 发布时间: 6年前

内容简介:最近受到比特币感染,所以就想看看比特币基本的加解密技术是怎样实现的。网上翻了好多篇文章,基本上都只是说了基本原理。完整的实现逻辑好像没怎么有。好吧,网上翻了老半天。从我抱着就只是来学习比特币的心态,就来看看喽。

最近受到比特币感染,所以就想看看比特币基本的加解密技术是怎样实现的。网上翻了好多篇文章,基本上都只是说了基本原理。完整的实现逻辑好像没怎么有。

好吧,网上翻了老半天。从 go 开始学习,一路学习了 go 的一大箩筐基础知识。说句实话,真没Node.js好学。有点不习惯,特别是模块的定义和引入。

我抱着就只是来学习比特币的心态,就来看看喽。

那就看看 go 的加密模块吧。大家都知道非对称加密,是有2把钥匙的:私钥和公钥。

公钥加密,私钥解密

比特币(BitCoin)非对称密钥使用基本分析

比特币这里主要使用私钥进行数字签名,然后使用公钥进行签名认证。

什么是数字签名可以查看 这篇文章

这里为什么不讲加密和解密,因为比特币的数据都是公开的,每个人都可以看得见。通过数字签名,保证比特币交易记录的真实性。( 安全是相对的

这篇文章主要讲比特币地址生成,以及比特币交易的基本数字签名和签名验证。

比特币(BitCoin)非对称密钥使用基本分析

这里为列一下主要的点:

  1. 比特币地址生成(上图步骤:1)
  2. 数字签名(上图步骤:2)
  3. 签名验证(上图步骤:3)

公钥和私钥生成

完成上面的3个步骤的前置条件就是要生成一对钥匙。那非对称加密算法有这么多,使用什么算法合适呢。

这里使用的是:椭圆曲线加密算法 - ECDSA

下面通过 ECDSA 加密算法生成2把钥匙。

//椭圆算法
curve := elliptic.P256()
//生成私钥,公钥
private, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
    log.Panic(err)
}
d := private.D.Bytes()
b := make([]byte, 0, privKeyBytesLen)
//私钥
priKey := paddedAppend(privKeyBytesLen, b, d)
//公钥
pubKey := append(private.PublicKey.X.Bytes(), private.PublicKey.Y.Bytes()...)

append 函数主要目的是将公钥的 xy 的值拼接起来。

通过 ECDSA 我们的到了一把私钥 priKey 和一把对应的公钥 pubKey

比特币地址生成

最重要的一个数据就是比特币地址。先来看看地址是如何生成的。

1. 公钥哈希值 = RIMPED160(SHA256(公钥))

2. 校验码 = 前四字节(SHA256(SHA256(0 + 公钥哈希值)))

3. 比特币地址 = 1 + Base58(0 + 公钥哈希值 + 校验码)

可以看到关键的就是如何求出公钥 hash ,以及校验码。

比特币(BitCoin)非对称密钥使用基本分析

公钥hash值

先使用 sha256 计算出哈希值,然后再使用 ripemd160 进行求值。

//hash公钥
h := sha256.New()
h.Write(pubKey)
fmt.Printf("sha256 pubKey: %02X\n", h.Sum(nil))

//ripemd160 hash
hasher := ripemd160.New()
hasher.Write(h.Sum(nil))
sha256Hash := hasher.Sum(nil)
fmt.Printf("公钥哈希值: ripemd160 sha256 hash: %02X\n", sha256Hash)

最后得到了 sha256Hash 公钥哈希值。

校验码

通过上面的计算得出了想要的公钥哈希值之后,可以计算校验码。通过2次 sha256 函数计算得出一个hash值,然后再取前面4字节。

//sha256Hash  公钥哈希值
pubKeyAddrSource := append([]byte{0x00} , sha256Hash...)
//校验码
verifyCode := sha256.New()
verifyCode.Write(pubKeyAddrSource)
verifyCodeHash := sha256.New()
verifyCodeHash.Write(verifyCode.Sum(nil))
verifyCode2 := verifyCodeHash.Sum(nil)
fmt.Printf("校验码: sha256(sha256) pubKey: %02X\n", verifyCode2[0:4])

//地址元数据
pubKeyAddrSource = append(pubKeyAddrSource , verifyCode2[0:4]...)
fmt.Printf("地址元数据: 0+公钥哈希值+校验码 : %02X\n", pubKeyAddrSource)

生成Addr

最后一步就是生成比特币地址, Base58 算法则是主要的。

先来看看 Base58 算法。使用它的主要目的是:

  1. 避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。
  2. 不使用”+”和”/”的原因是非字母或数字的字符串作为帐号较难被接受。
  3. 没有标点符号,通常不会被从中间分行。
  4. 大部分的软件支持双击选择整个字符串。
// b58encode encodes a byte slice b into a base-58 encoded string.
func b58encode(b []byte) (s string) {
    /* See https://en.bitcoin.it/wiki/Base58Check_encoding */
    const BITCOIN_BASE58_TABLE = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
    /* Convert big endian bytes to big int */
    x := new(big.Int).SetBytes(b)
    /* Initialize */
    r := new(big.Int)
    m := big.NewInt(58)
    zero := big.NewInt(0)
    s = ""
    /* Convert big int to string */
    for x.Cmp(zero) > 0 {
        /* x, r = (x / 58, x % 58) */
        x.QuoRem(x, m, r)
        /* Prepend ASCII character */
        s = string(BITCOIN_BASE58_TABLE[r.Int64()]) + s
    }
    return s
}

使用上面的 b58encode 生成比特币地址。

//地址
pubKeyAddr := b58encode(pubKeyAddrSource)

for _, v := range pubKeyAddrSource {
    if v != 0 {
        break
    }
    pubKeyAddr = "1" + pubKeyAddr
}

fmt.Println("地址: b58encode : ", pubKeyAddr)

到这里,就已经可以得到想要的比特币地址了。

数字签名

有了私钥,你就可以对文本签名。别人拿了你的公钥就可以根据签名认证你是否拥有私钥。在比特币中,这就是证明你拥有存款的办法。

//获取钥匙
key := createKey()
priKey := ecdsa.PrivateKey{}
//椭圆算法
curve := elliptic.P256()
priKey.D = new(big.Int).SetBytes(key.PrivateKey)

pub := ecdsa.PublicKey{}
pub.Curve = curve
pub.X = key.PublicKey.X
pub.Y = key.PublicKey.Y

priKey.PublicKey = pub
//进行数据签名
r , s , hash , err := createSign(&priKey , []byte("这是我的钱"))

签名验证

验证的时候需要提供签名和公钥,算出公钥哈希值并和比特币支出脚本的公钥哈希值对比,最后再验证签名。

if ecdsa.Verify(&pub ,hash , r , s) {
    fmt.Println("is ok")
}else {
    fmt.Println("is error")
}

到这里比特币基本的基本原理就分析完成来。

效果图

比特币(BitCoin)非对称密钥使用基本分析

代码: https://github.com/Yi-love/go-demo/blob/master/publickey.go

参考资料

椭圆曲线加密算法

比特币加密算法

base58


以上所述就是小编给大家介绍的《比特币(BitCoin)非对称密钥使用基本分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Visual C# 2008入门经典

Visual C# 2008入门经典

James Foxall / 张劼 / 人民邮电出版社 / 2009-6 / 39.00元

《Visual C#2008入门经典》分为五部分,共24章。第一部分介绍了Visual C# 2008速成版开发环境,引导读者熟练使用该IDE;第二部分探讨如何创建应用程序界面,包含窗体和各种控件的用法;第三部分介绍了编程技术,包括编写和调用方法、处理数值、字符串和日期、决策和循环结构、代码调试、类和对象的创建以及图形绘制等;第四部分阐述了文件和注册表的处理、数据库的使用和自动化其他应用程序等;第......一起来看看 《Visual C# 2008入门经典》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具