深入理解比特币(三) 交易

"交易"是比特币系统中的核心部分, 所谓交易, 是指资产从一个所有者转移到另一个所有者的过程.本篇文章主要包含以下内容: 熟悉比特币交易的数据结构 理解比特币钱包余额和 UTXO 模型 了解比特币编程语言 学习利用 P2SH(Pay-to-Script Hash) 构造复杂交易 数据结构 一笔比特币交易由如下几个组成部分: Version Inputs Outputs Locktime Version(版本号) 和大多数版本号的作用一样, 比特币交易的版本号是为了标识处理该笔交易所需要的支持的特性. 比特币系统也是一个持续迭代的软件, 有时我们需要为交易设置不同的版本号以便交易中的新特性能被更好地支持. 目前比特币系统中大多数交易的版本号为 2. 版本号位于序列化交易数据最开始的位置, 占 4 个字节. Inputs(输入) 和 Outputs(输出) 在比特币的设计里, 比特币钱包(私钥)所拥有的余额不是以一个单独数字的形式存在的. 比特币世界中的余额与现实世界中现金的模式类似, 在一次交易中: 每一个输入就像是我们此前从别人那里收到的钱 每一个输出就像是我们这次要交给其他人的钱 每笔交易可以包含多笔输入(一次使用之前收到多张现金)…

深入理解比特币(二) 钱包和地址

钱包是比特币世界里最重要的概念之一. 这里要说的钱包并不是指具体的某种软件或硬件产品, 而是其更本质的定义: 私钥即钱包. 比特币之所以被被称作加密货币是因为它的实现是建立在椭圆曲线密码学的基础之上的. 在比特币的世界里, 资产以一种被称作 UTXO (unspent transaction outputs) 的数据形式存在. 比特币 UTXO 对网络里的所有用户都是可见的, 谁能够提供一个凭证(在密码学中这样的凭证一般被称为"见证" Witness)使 UTXO 中预先设定花费条件成立, 谁就拥有了这笔资产的所有权. 而私钥正是能提供这个凭证的关键所在. 掌握了某个私钥也就意味拥有了与该私钥对应的所有资产. 关于椭圆曲线密码学的知识可以参考我翻译的 椭圆曲线密码学: 入门 系列文章, 文章的原作者是来自爱尔兰亚马逊的软件工程师, 这几篇文章也是我读过的关于介绍椭圆曲线密码学最好的入门文章, 有兴趣的朋友可以前往阅读, 相信也会让你受益匪浅. 私钥,公钥和地址 在椭圆曲线密码学中, 私钥 e 是一个随机数, 而对应的公钥是私钥和椭圆曲线上的特定生成点 G 相乘得到的另一个点 P. 即: $$ P = eG $$ 由于受到椭圆曲线上的离散对数难题的限制(这也是椭圆曲线密码学的根基)…

深入理解比特币(一) 简史

第一次听说比特币还是在 2012 年, 那年我读大三, 距离中本聪发表《比特币: 对等网络电子现金系统》论文仅有 3 年多的时间. 那时的我不会想到, 在几年之后我自己会进入到加密货币这个行业, 从而使我有机会能够更加深入地思考比特币到底是什么. 本系列文章由以下五篇构成: 深入理解比特币(一) 简史 深入理解比特币(二) 钱包和地址 深入理解比特币(三) 交易 深入理解比特币(四) 区块和网络 深入理解比特币(五) Atomic Swap 跨链交易 这些内容里包含了我对比特币的理解与思考. 当然, 作为一个技术人, 更多的内容还是关于对比特币技术细节的解读. 希望读者在读完本系列文章后, 能透过技术对比特币甚至是整个加密货币行业有更多的感悟. 货币 要了解什么是比特币, 我们必须先思考什么是货币? 人类使用货币的历史产生于物物交换的时代. 在原始社会, 人们使用以物易物的方式交换自己所需要的物资, 比如一头羊换一把石斧. 以物易物模式最大的问题在于要达成交易必须满足双重偶然性, 即"我想要的东西刚好你有, 而你想要的东西刚好我有"…

[译] 椭圆曲线密码学: 安全强度及对比RSA

本文翻译自爱尔兰AWS工程师 ANDREA CORBELLINI 关于椭圆曲线密码学四篇博客中的最后一篇, 原文采用 CC-BY 4.0 协议 进行授权 原文链接 : https://andrea.corbellini.name/2015/06/08/elliptic-curve-cryptography-breaking-security-and-a-comparison-with-rsa/ 原作者: ANDREA CORBELLINI 译者: chxj1992 本文是 ECC:入门 系列文章的第四篇也是最后一篇. 在上一篇文章中我们学习了两种算法: ECDH 和 ECDSA, 并且了解到了椭圆曲线上的离散对数难题在保证算法安全性上扮演的重要角色. 但是如果你还没忘的话, 我们并没有对离散对数难题的复杂性在数学上的证明: 我们相信它是"困难的", 但是我们还不能肯定. 在本文的第一个部分中, 我们将试着去了解在今天的技术条件下要解决它到底有多"难". 然后在第二个部分里, 我们将尝试解答以下问题: 既然已经有了 RSA 为什么我们需要椭圆曲线加密.…

[译] 椭圆曲线密码学: ECDH 和 ECDSA

本文翻译自爱尔兰AWS工程师 ANDREA CORBELLINI 关于椭圆曲线密码学四篇博客中的第三篇, 原文采用 CC-BY 4.0 协议 进行授权 原文链接 : https://andrea.corbellini.name/2015/05/30/elliptic-curve-cryptography-ecdh-and-ecdsa/ 原作者: ANDREA CORBELLINI 译者: chxj1992 这篇文章是 ECC:入门 系列文章的第三篇. 在之前的文章中, 我们了解了什么是椭圆曲线以及定义了群律以便对椭圆曲线上的点进行一些数学计算.然后我们将椭圆曲线限定在了以一个质数为模的整数有限域上. 在此限制下, 我们看到了椭圆曲线上的点可以生成出循环子群并且我们还介绍了 基点, 阶 和 余子式 的概念. 最后我们知道, 有限域上的标量乘法计算是一个"容易"的问题, 而离散对数问题却是非常"困难"的. 现在我们将会看到以上这些东西将如何融入密码学中.…

[译] 椭圆曲线密码学: 有限域和离散对数

本文翻译自爱尔兰AWS工程师 ANDREA CORBELLINI 关于椭圆曲线密码学四篇博客中的第二篇, 原文采用 CC-BY 4.0 协议 进行授权 原文链接 : https://andrea.corbellini.name/2015/05/23/elliptic-curve-cryptography-finite-fields-and-discrete-logarithms/ 原作者: ANDREA CORBELLINI 译者: chxj1992 这篇文章是椭圆曲线密码学:入门系列文章的第二篇. 在前一篇文章中, 我们知道了如何在实数域上的椭圆曲线上定义一个群. 具体来说, 我们定义了点加的规则: 找到位于一条直线上的三个点, 三点之和为零($P + Q + R = 0$). 我们推导了求解点加的几何方法与代数方法. 我们还介绍了标量乘法($nP = P + P + \cdots + P$) 并且我们找到了一种用于计算标量乘法的"简单"算法: 倍加法. 现在我们将要把椭圆曲线限制在有限域而非所有实数的集合上,…

[译] 椭圆曲线密码学: 入门

本文翻译自爱尔兰AWS工程师 ANDREA CORBELLINI 关于椭圆曲线密码学四篇博客中的第一篇, 原文采用 CC-BY 4.0 协议 进行授权 原文链接 : https://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/ 原作者: ANDREA CORBELLINI 译者: chxj1992 如果你们知道什么是椭圆曲线密码学, 那你们应该也听说过 ECC, ECD或者ECDSA. ECC是椭圆曲线密码学(Elliptic Curve Cryptography)的首字母缩写, 而另外两个都是基于ECC实现的算法. 如今, 我们在 TLS, PGP 和 SSH 里都能找到椭圆曲线密码学的身影, 这三种技术可以说是现代互联网和数字世界的基础, 更别提ECC在比特币和其他各种加密货币中发挥的巨大作用了. 在ECC开始流行以前, 绝大多数公钥加密算法都基于 RSA, DSA 和 DH 实现.…

FastJSON IntegerSerializer 潜在DOS攻击风险问题

背景 近日, 慢雾安全平台的白帽子给公司项目提交了一个安全漏洞: 向某个参数类型为Integer的POST接口提交如 1.00...00 (小数点后约100万个0), 服务端程序处理该请求消耗了约90秒的时间, 耗费了大量的计算资源, 对于服务端程序来说, 这是不可接受的, 攻击者可以利用该漏洞对服务器发起DOS攻击 分析 根据白帽子提供的细心我在测试环境对该问题进行了复现并通过JProfiler分析了请求链路, 结果如下 : 可见, 绝大部分的计算资源用在了将数据解析为BigDecimal. 可是为什么参数类型明明是Integer却被解析成了BigDecimal ? 我结合FastJSON源码做了进一步的分析, 发现FastJSON在解析Integer过程中会先判断数据的格式, 如果数据格式是小数, FastJSON会先将数据解析为BigDecimal , 再通过类型转换把BigDecimal转成Integer, 而正是这样的设计导致了这次的问题. 对比同类库Jackson和GSON, 在将相同数据转换成Integer时并没有以上问题. 我认为这可能是FastJSON在设计时考虑不周的一个点 解决方案 a. 在运维层面, 根据接口实际需要对请求参数大小进行限制, 除数据上传等提交数据较大的接口之外外, 将入参数据大小限制在 10K 内 b. 编写自定义Integer解析器替代默认的Integer解析器, 在将格式为小数的数据解析为Integer时, 用Double替代BigDecimal以规避潜在的安全(DOS)风险, 相关代码如下 c. 在涉及到解析用户提交的数据时, 谨慎使用BigDecimal类型, 当确实需要准确精度保证时, 可以考虑先将小数数据转换为String类型, 在校验数据长度后再将数据转为BigDecimal 这次的问题也给我带来了一些的思考:…

V2Ray+Cloudflare搭建"永不被墙"的梯子

之前一直在自己的VPS搭建Shadowsocks服务端做梯子, 不过在一些政治敏感时期, 墙的力度会增强, 前段时间我发现Vultr的所有IP几乎都直接被墙了 经过了解, 决定改用V2Ray搭建一个新的梯子. 我觉得V2Ray最牛逼的一个点是可以将流量伪装成Websocket并通过Cloudflare(CDN)来代理, 而CDN整个被墙掉的概率很低的 ... 建议使用这个项目来搭建V2Ray服务端, 非常好用 速度方面可以接受, Google查个资料, YouTube看个视频基本还是没问题的…

读<跨越千年的RSA算法>

原文链接 跨越千年的RSA算法 在当今这个由互联网构筑的世界里, RSA算法几乎无处不在. 例如: 访问任何一个https证书加密的网站 通过SSH登录一台服务器 从GitHub上clone一个项目 说来惭愧, 作为一个每天和RSA算法打交道的程序员, 直到最近学习了Matrix67大神讲解RSA算法的博客我才终于理解RSA算法到底是怎么一回事. 在真正介绍RSA算法之前作者用了大量的篇幅为读者填补了必要的数学基础, 文章共分为六个小节, 真正提到RSA算法的只有最后一个小节, 我之前也看过一两篇其他介绍RSA算法的文章, 但唯有这一次让我有种豁然开朗的感觉. (一)可公度线段 文章介绍了在<几何原本>中一种求取最大公约数的方法(Euclid 算法): 假设刚开始的两个数是 a 和 b ,其中 a > b ,那么把 a 除以 b 的余数记作 c ,把 b 除以 c 的余数记作 d ,c 除以 d 余 e…