# 加密与签名 ## 加密算法 缩写 | 英文全名 | 中文翻译 ---|---| --- EC |Elliptic Curve |椭圆曲线 ECC | Elliptic Curve Cryptogphay | 椭圆曲线密码学 ECDSA | Elliptic Curve Digital Signature Algorithm | 椭圆曲线数字签名算法 DH | Diffie-Hellman Key Exchange Diffie-Hellman |密钥交换 ECDH | Elliptic Curve Diffie-Hellman Key Exchange | 椭圆曲线Diffie-Hellman密钥交换 IES |Integrated Encryption Schema |集成加密框架 ECIES | Elliptic Curve Integrated Encryption Schema |椭圆曲线集成加密框架 KDF |Key Derivation Function| 密钥(私钥)生成函数 ## 椭圆曲线加密(ECC:Elliptic Curve Cryptography) ### 1. 原理性质 椭圆曲线加密法是一种基于离散对数问题的非对称加密法,可以用对椭圆曲线上的点进行加法或乘法运算来表达。 下图是一个椭圆曲线的示例,类似于比特币所用的曲线。 secp256k1 ```math y^2 = (x^3 + 7) \over (F_p) y^2 \bmod p = (x^3 + 7) \bmod p ``` 上述mod p(素数p取模)表明该曲线是在素数阶p的有限域内,也写作Fp,其中p = 2^256 – 2^32 – 2^9 – 2^8 – 2^7 – 2^6 – 2^4 – 1, 这是个非常大的素数 ### 数字签名(ECDSA) BTC数字签名算法是椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm)或ECDSA。 ECDSA用于脚本函数`OP_CHECKSIG`,`OP_CHECKSIGVERIFY`,`OP_CHECKMULTISIG`和`OP_CHECKMULTISIGVERIFY`。 数字签名在比特币中有三种用途。 - 第一,签名证明私钥的所有者,即资金所有者,已经授权支出这些资金 - 第二,授权证明是不可否认的(不可否认性) - 第三,签名证明交易(或交易的具体部分)在签字之后没有也不能被任何人修改。 **通常使用椭圆曲线算法生成密钥对** - 比特币密钥长度:256位 - 公钥哈希值=RIMPED160(SHA256(公钥)) - 比特币地址=*1*+Base58(0+公钥哈希值+校验码) - 校验码=前四字节(SHA256(SHA256(0+公钥哈希值))) **签名** - 发送方使用HASH算法计算数据的HASH值 - 发送方使用本方的私钥加密HASH值,得到签名 - 接收方使用HASH算法计算数据的HASH值 - 接收方使用发送方的公钥解密签名得到发送的HASH值 - 比较两个HASH值的一致性 ### 数字签名如何工作 数字签名是一种由两部分组成的数学方案: - 第一部分是使用私钥(签名密钥)从消息(交易)创建签名的算法; - 第二部分是允许任何人验证签名的算法,给定消息和公钥。 #### 创建签名 在比特币的ECDSA算法的实现中,被签名的“消息”是交易,或更确切地说是交易中特定数据子集的哈希值(参见签名哈希类型(SIGHASH))。签名密钥是用户的私钥,结果是签名: ```math Sig = F{sig}(F{hash}(m), dA) ``` - dA 是签名私钥 - m 是交易(或其部分) - Fhash 是散列函数 - Fsig 是签名算法 - Sig 是结果签名 函数` Fsig `产生由两个值组成的签名Sig,通常称为R和S: #### 验证签名 要验证签名,必须有签名(R和S)、序列化交易和公钥(对应于用于创建签名的私钥)。本质上,签名的验证意味着“只有生成此公钥的私钥的所有者,才能在此交易上产生此签名。” 签名验证算法采用消息(交易或其部分的哈希值)、签名者的公钥和签名(R和S值),如果签名对该消息和公钥有效,则返回 TRUE 值。 #### ECDSA数学 签名由产生由两个值R和S组成的签名的数学函数`Fsig` 创建。 签名算法首先生成一个 ephemeral(临时)私公钥对。 在涉及签名私钥和交易哈希的变换之后,该临时密钥对用于计算R和S值。 临时密钥对基于随机数k,用作临时私钥。 从k,我们生成相应的临时公钥P(以P = k * G计算,与派生比特币公钥相同);参见[pubkey]部分)。数字签名的R值则是临时公钥P的x坐标。 ## 2. 常用库 #### JavaScript : ##### [Elliptic](https://github.com/indutny/elliptic) 支持以下曲线 - secp256k1 **==ECDSA==** - p192 - p224 - p256 - p384 - p521 - curve25519 **==ECDH==** - ed25519 **==EdDSA==** ##### [Eccrypto](https://github.com/bitchan/eccrypto) Only secp256k1 curve **==ECDSA==** **==ECDH==** **==ECIES==** ##### [tiny-secp256k1](https://github.com/bitcoinjs/tiny-secp256k1) ##### [crypto-browserify](https://github.com/crypto-browserify/crypto-browserify) 实现以下: * createHash (sha1, sha224, sha256, sha384, sha512, md5, rmd160) * createHmac (sha1, sha224, sha256, sha384, sha512, md5, rmd160) * pbkdf2 * pbkdf2Sync * randomBytes * pseudoRandomBytes * createCipher (aes) * createDecipher (aes) * createDiffieHellman * createSign (rsa, ecdsa) * createVerify (rsa, ecdsa) * createECDH (secp256k1) * publicEncrypt/privateDecrypt (rsa) * privateEncrypt/publicDecrypt (rsa) ### 参考如下: [椭圆曲线密码学相关概念与开源实现](https://blog.xiaofuxing.name/2017/05/10/more_on_ecc.html) [精通比特币 - 密钥和地址](https://wizardforcel.gitbooks.io/masterbitcoin2cn/content/ch04.html)