【比特币】脑钱包
来源:互联网 发布:变魔术的软件 编辑:程序博客网 时间:2024/06/03 00:26
代码参考
https://github.com/openssl/openssl/blob/master/crypto/ec/ec_key.c
https://github.com/openssl/openssl/blob/master/apps/ecparam.c
查看手册:man --manpath=/d/local/ssl/man OBJ_sn2nid
基本步骤
1) 创建EC_KEY结构体
EC_KEY *EC_KEY_new(void){EC_KEY *ret;ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));if (ret == NULL){ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);return(NULL);}ret->version = 1;ret->flags = 0;ret->group = NULL;ret->pub_key = NULL;ret->priv_key= NULL;ret->enc_flag= 0; ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;ret->references= 1;ret->method_data = NULL;return(ret);}
以上创建的EC_KEY的group成员是空的,需要调用
EC_KEY_set_group(eckey,group)
来设置group参数。
从曲线名称可以得到group参数结构
int nid = OBJ_sn2nid(curve_name);int nid = EC_curve_nist2nid(curve_name);EC_GROUP * group = EC_GROUP_new_by_curve_name(nid);
也可以直接从curve_name创建EC_KEY结构体并设置EC_GROUP成员
EC_KEY *EC_KEY_new_by_curve_name(int nid){EC_KEY *ret = EC_KEY_new();if (ret == NULL)return NULL;ret->group = EC_GROUP_new_by_curve_name(nid);if (ret->group == NULL){EC_KEY_free(ret);return NULL;}return ret;}
2) 销毁结构体
void EC_KEY_free(EC_KEY *r){int i;if (r == NULL) return;i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);#ifdef REF_PRINTREF_PRINT("EC_KEY",r);#endifif (i > 0) return;#ifdef REF_CHECKif (i < 0){fprintf(stderr,"EC_KEY_free, bad reference count\n");abort();}#endifif (r->group != NULL) EC_GROUP_free(r->group);if (r->pub_key != NULL)EC_POINT_free(r->pub_key);if (r->priv_key != NULL)BN_clear_free(r->priv_key);EC_EX_DATA_free_all_data(&r->method_data);OPENSSL_cleanse((void *)r, sizeof(EC_KEY));OPENSSL_free(r);}
3) 生成EC_KEY的私钥和公钥
int EC_KEY_generate_key(EC_KEY *eckey){intok = 0;BN_CTX*ctx = NULL;BIGNUM*priv_key = NULL, *order = NULL;EC_POINT *pub_key = NULL;#ifdef OPENSSL_FIPSif(FIPS_selftest_failed()){FIPSerr(FIPS_F_EC_KEY_GENERATE_KEY,FIPS_R_FIPS_SELFTEST_FAILED);return 0;}#endifif (!eckey || !eckey->group){ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);return 0;}if ((order = BN_new()) == NULL) goto err;if ((ctx = BN_CTX_new()) == NULL) goto err;if (eckey->priv_key == NULL){priv_key = BN_new();if (priv_key == NULL)goto err;}elsepriv_key = eckey->priv_key;if (!EC_GROUP_get_order(eckey->group, order, ctx))goto err;#ifdef OPENSSL_FIPSif (!fips_check_ec_prng(eckey))goto err;#endifdo // 开始随机化私钥数据,脑钱包可以在这里设置随机数据(256bits的Hash)if (!BN_rand_range(priv_key, order))goto err;while (BN_is_zero(priv_key));if (eckey->pub_key == NULL){pub_key = EC_POINT_new(eckey->group);if (pub_key == NULL)goto err;}elsepub_key = eckey->pub_key;if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))goto err;eckey->priv_key = priv_key;eckey->pub_key = pub_key;#ifdef OPENSSL_FIPSif(!fips_check_ec(eckey)){eckey->priv_key = NULL;eckey->pub_key = NULL; goto err;}#endifok=1;err:if (order)BN_free(order);if (pub_key != NULL && eckey->pub_key == NULL)EC_POINT_free(pub_key);if (priv_key != NULL && eckey->priv_key == NULL)BN_free(priv_key);if (ctx != NULL)BN_CTX_free(ctx);return(ok);}
4) 如何使用自定义的私钥数据
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key){if (key->priv_key)BN_clear_free(key->priv_key);key->priv_key = BN_dup(priv_key);return (key->priv_key == NULL) ? 0 : 1;}
但是设置新的私钥数据并不会导致EC_KEY_generate_key去计算新的公钥。
所以比特币的代码里面加入了EC_KEY_regenerate_key()这个实现。
openssl始终是使用BN_rand_range(,,,)来设置私钥数据。
5) 打印结果
EC_KEY_print_fp(FILE * stdout, EC_KEY * eckey, int offset);
使用openssl官方例子生成私钥的方式(随机私钥)
#include <openssl/opensslconf.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <openssl/ec.h>#include <openssl/objects.h>int main(int argc, char * argv[]){int nid;EC_KEY * eckey ;//= NULL;eckey = EC_KEY_new();nid = OBJ_sn2nid("secp256k1");EC_GROUP * group = EC_GROUP_new_by_curve_name(nid);EC_KEY_set_group(eckey, group);EC_KEY_generate_key(eckey); EC_KEY_print_fp(stdout, eckey, 0);EC_KEY_free(eckey);return 0;}
编译:
g++ -DMONOLITH -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_EC_BIN_PT_COMP -Wa,--noexecstack -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -DOPENSSL_BN_ASM_PART_WORDS -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DRMD160_ASM -DAES_ASM -DVPAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -I/d/local/include -L/d/local/lib -O0 -g brainwallet.c -o brainwallet -lcrypto -ldl
测试:
localhost ~ # ./brainwallet Private-Key: (256 bit)priv: 00:d5:28:8d:89:65:ba:29:5b:e3:75:68:de:3f:db: a2:17:16:d7:ed:ca:ce:06:63:7f:0e:c9:bc:94:b4: a6:04:e3pub: 04:9b:01:ab:2d:da:2e:9e:47:90:89:7a:ba:59:d2: 52:19:de:8d:51:a2:51:74:db:44:c0:8c:a2:ab:36: 81:6c:5c:cf:c5:71:c9:e2:e4:fd:dd:78:50:e1:0e: c9:85:49:84:a3:1f:cf:4c:f1:e5:0a:ad:bf:0e:4b: 0a:b7:85:67:9dField Type: prime-fieldPrime: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe:ff: ff:fc:2fA: 0B: 7 (0x7)Generator (uncompressed): 04:79:be:66:7e:f9:dc:bb:ac:55:a0:62:95:ce:87: 0b:07:02:9b:fc:db:2d:ce:28:d9:59:f2:81:5b:16: f8:17:98:48:3a:da:77:26:a3:c4:65:5d:a4:fb:fc: 0e:11:08:a8:fd:17:b4:48:a6:85:54:19:9c:47:d0: 8f:fb:10:d4:b8Order: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:fe:ba:ae:dc:e6:af:48:a0:3b:bf:d2:5e:8c:d0: 36:41:41Cofactor: 1 (0x1)
Secp256k1
secp256k1 refers to the parameters of the ECDSA curve used in Bitcoin, and is defined in Standards for Efficient Cryptography (SEC) (Certicom Research, http://www.secg.org/collateral/sec2_final.pdf).
secp256k1 was almost never used before Bitcoin became popular, but it is now gaining in popularity due to its several nice properties. Most commonly-used curves have a random structure, but secp256k1 was constructed in a special non-random way which allows for especially efficient computation. As a result, it is often more than 30% faster than other curves if the implementation is sufficiently optimized. Also, unlike the popular NIST curves, secp256k1's constants were selected in a predictable way, which significantly reduces the possibility that the curve's creator inserted any sort of backdoor into the curve.
Technical details
As excerpted from Standards:
The elliptic curve domain parameters over Fp associated with a Koblitz curve secp256k1 are specified by the sextuple T = (p,a,b,G,n,h) where the finite field Fp is defined by:
- p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
- = 2256 - 232 - 29 - 28 - 27 - 26 - 24 - 1
The curve E: y2 = x3+ax+b over Fp is defined by:
- a = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
- b = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007
The base point G in compressed form is:
- G = 0279BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
and in uncompressed form is:
- G = 0479BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
Finally the order n of G and the cofactor are:
- n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
- h = 01
从上面这些参数可以看出,官方oepnssl ecparam -genkey的实现,
使用BN_rand_range(privkey, maxrange=FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141)。
比特币官方代码的实现方式
1) 从随机数数组设置私钥
void SetSecretBytes(const unsigned char vch[32]) { // 设置32字节的数组到大整数(256b)bool ret;BIGNUM bn;BN_init(&bn);ret = BN_bin2bn(vch, 32, &bn);assert(ret);ret = EC_KEY_regenerate_key(pkey, &bn);// 生成私钥和公钥assert(ret);BN_clear_free(&bn);}
2) 从随机数生成公钥和私钥
// Generate a private key from just the secret parameterint EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key){ int ok = 0; BN_CTX *ctx = NULL; EC_POINT *pub_key = NULL; if (!eckey) return 0; const EC_GROUP *group = EC_KEY_get0_group(eckey); // 获取ec计算群 if ((ctx = BN_CTX_new()) == NULL) goto err; pub_key = EC_POINT_new(group); // (x,y)坐标 if (pub_key == NULL) goto err; if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) // 公钥=私钥×基点 goto err; EC_KEY_set_private_key(eckey,priv_key); EC_KEY_set_public_key(eckey,pub_key); ok = 1;err: if (pub_key) EC_POINT_free(pub_key); if (ctx != NULL) BN_CTX_free(ctx); return(ok);}
3) 修改后的例子用测试数据重新生成
#include <openssl/opensslconf.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <openssl/ec.h>#include <openssl/objects.h>#include <openssl/bn.h>#include <assert.h>// Generate a private key from just the secret parameterint EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key){ int ok = 0; BN_CTX *ctx = NULL; EC_POINT *pub_key = NULL; if (!eckey) return 0; const EC_GROUP *group = EC_KEY_get0_group(eckey); // 获取ec计算群 if ((ctx = BN_CTX_new()) == NULL) goto err; pub_key = EC_POINT_new(group); // (x,y)坐标 if (pub_key == NULL) goto err; if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) // 公钥=私钥×基点 goto err; EC_KEY_set_private_key(eckey,priv_key); EC_KEY_set_public_key(eckey,pub_key); ok = 1;err: if (pub_key) EC_POINT_free(pub_key); if (ctx != NULL) BN_CTX_free(ctx); return(ok);}// 从32字节数组重新设置EC_KEY结构void SetSecretBytes(EC_KEY * pkey, const unsigned char vch[32]) { // 设置32字节的数组到大整数(256b)bool ret;BIGNUM bn;BN_init(&bn);ret = BN_bin2bn(vch, 32, &bn);assert(ret);ret = EC_KEY_regenerate_key(pkey, &bn);// 生成私钥和公钥assert(ret);BN_clear_free(&bn);}int main(int argc, char * argv[]){unsigned char vch[32];int nid;EC_KEY * eckey ;//= NULL;eckey = EC_KEY_new();nid = OBJ_sn2nid("secp256k1");EC_GROUP * group = EC_GROUP_new_by_curve_name(nid);EC_KEY_set_group(eckey, group);// 官方的随机数方式生成EC_KEYEC_KEY_generate_key(eckey);// 打印结果EC_KEY_print_fp(stdout, eckey, 0);// 设置随机数memset(vch, 0xa0, sizeof(vch));// 重新计算SetSecretBytes(eckey, vch);// 打印结果EC_KEY_print_fp(stdout, eckey, 0);EC_KEY_free(eckey);return 0;}
localhost ~ # ./brainwallet Private-Key: (256 bit)priv://随机数组成的私钥 00:e6:86:5e:09:25:b6:48:e8:50:7b:25:91:2b:cf: 9d:6f:82:61:f1:3e:b9:12:d6:74:87:c4:39:77:b1: cc:c8:c1pub: 04:54:f4:b6:19:e3:c6:74:d4:ec:ae:b0:e2:df:10: 95:b2:03:48:59:0b:ff:c6:41:1c:ec:da:d6:9b:5f: 81:32:cb:3d:06:6d:5f:15:a4:cb:a5:97:1b:d2:5c: ec:0f:7e:2b:a6:b7:c0:57:91:62:87:b2:b9:bd:6a: 35:f4:f2:e8:9fField Type: prime-fieldPrime: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe:ff: ff:fc:2fA: 0B: 7 (0x7)Generator (uncompressed): 04:79:be:66:7e:f9:dc:bb:ac:55:a0:62:95:ce:87: 0b:07:02:9b:fc:db:2d:ce:28:d9:59:f2:81:5b:16: f8:17:98:48:3a:da:77:26:a3:c4:65:5d:a4:fb:fc: 0e:11:08:a8:fd:17:b4:48:a6:85:54:19:9c:47:d0: 8f:fb:10:d4:b8Order: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:fe:ba:ae:dc:e6:af:48:a0:3b:bf:d2:5e:8c:d0: 36:41:41Cofactor: 1 (0x1)
Private-Key: (256 bit)priv://用户设置的私钥 00:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0: a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0:a0: a0:a0:a0pub: 04:d5:4c:d3:79:30:b0:c5:58:73:33:d5:5b:f4:84: 18:43:a9:22:a5:af:75:46:81:8b:a8:ac:2c:5c:fa: 2c:f9:3d:c8:a9:86:2d:8d:b5:97:49:44:b7:cf:ea: 53:03:92:80:ab:b7:cd:26:dd:f4:a5:28:b4:67:4b: 68:d0:73:e0:57Field Type: prime-fieldPrime: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe:ff: ff:fc:2fA: 0B: 7 (0x7)Generator (uncompressed): 04:79:be:66:7e:f9:dc:bb:ac:55:a0:62:95:ce:87: 0b:07:02:9b:fc:db:2d:ce:28:d9:59:f2:81:5b:16: f8:17:98:48:3a:da:77:26:a3:c4:65:5d:a4:fb:fc: 0e:11:08:a8:fd:17:b4:48:a6:85:54:19:9c:47:d0: 8f:fb:10:d4:b8Order: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:fe:ba:ae:dc:e6:af:48:a0:3b:bf:d2:5e:8c:d0: 36:41:41Cofactor: 1 (0x1)
那么,脑钱包的雏形基本上就出来的。对任意数据做一次sha256sum得到256bit的hash值,用这个值作为vch的值,重新计算机可以到相应的公钥。
4)从用户命令行指定的hash值生成
#include <openssl/opensslconf.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <openssl/ec.h>#include <openssl/objects.h>#include <openssl/bn.h>#include <assert.h>#include <string>#include <vector>const signed char p_util_hexdigit[256] ={ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };signed char HexDigit(char c){ return p_util_hexdigit[(unsigned char)c];}std::vector<unsigned char> ParseHex(const char* psz){ // convert hex dump to vector std::vector<unsigned char> vch; while (true) { while (isspace(*psz)) psz++; signed char c = HexDigit(*psz++); if (c == (signed char)-1) break; unsigned char n = (c << 4); c = HexDigit(*psz++); if (c == (signed char)-1) break; n |= c; vch.push_back(n); } return vch;}// Generate a private key from just the secret parameterint EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key){ int ok = 0; BN_CTX *ctx = NULL; EC_POINT *pub_key = NULL; if (!eckey) return 0; const EC_GROUP *group = EC_KEY_get0_group(eckey); // 获取ec计算群 if ((ctx = BN_CTX_new()) == NULL) goto err; pub_key = EC_POINT_new(group); // (x,y)坐标 if (pub_key == NULL) goto err; if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) // 公钥=私钥×基点 goto err; EC_KEY_set_private_key(eckey,priv_key); EC_KEY_set_public_key(eckey,pub_key); ok = 1;err: if (pub_key) EC_POINT_free(pub_key); if (ctx != NULL) BN_CTX_free(ctx); return(ok);}// 从32字节数组重新设置EC_KEY结构void SetSecretBytes(EC_KEY * pkey, const std::string & sHexString) { // 十六进制字符串数组bool ret;BIGNUM * bn = NULL;ret = BN_hex2bn(&bn, sHexString.c_str());// 大端形式的16进制数组转换成bigNumber来运算 // 如果长度超多64字节(256bit),那么计算结果是错误的; // 整数溢出了,但是openssl不会检测这个错误。assert(ret);ret = EC_KEY_regenerate_key(pkey, bn);// 生成私钥和公钥assert(ret);BN_clear_free(bn);bn = NULL;}int main(int argc, char * argv[]){int nid;EC_KEY * eckey;eckey = EC_KEY_new();nid = OBJ_sn2nid("secp256k1");EC_GROUP * group = EC_GROUP_new_by_curve_name(nid);EC_KEY_set_group(eckey, group);// 官方的随机数方式生成EC_KEYEC_KEY_generate_key(eckey);// 重新计算SetSecretBytes(eckey, argv[1]);// 打印结果EC_KEY_print_fp(stdout, eckey, 0);EC_KEY_free(eckey);return 0;}
5) 测试结果:
localhost ~ # ./brainwallet aaaabbbbccccdddd0000111122223333aaaabbbbccccdddd0000111122223333Private-Key: (256 bit)priv: 00:aa:aa:bb:bb:cc:cc:dd:dd:00:00:11:11:22:22: 33:33:aa:aa:bb:bb:cc:cc:dd:dd:00:00:11:11:22: 22:33:33pub: 04:18:13:fc:6a:a4:2f:e3:b0:f1:82:d1:c8:b3:29: 68:81:b3:c9:ad:b7:ac:eb:88:d1:ff:10:1d:d7:bc: d3:48:a0:93:b3:d1:8f:7c:4e:d1:8d:0b:61:1a:35: 1d:3e:cf:70:aa:a0:7b:87:67:4f:1b:34:fe:6a:bd: a8:e8:48:24:d4Field Type: prime-fieldPrime: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe:ff: ff:fc:2fA: 0B: 7 (0x7)Generator (uncompressed): 04:79:be:66:7e:f9:dc:bb:ac:55:a0:62:95:ce:87: 0b:07:02:9b:fc:db:2d:ce:28:d9:59:f2:81:5b:16: f8:17:98:48:3a:da:77:26:a3:c4:65:5d:a4:fb:fc: 0e:11:08:a8:fd:17:b4:48:a6:85:54:19:9c:47:d0: 8f:fb:10:d4:b8Order: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:fe:ba:ae:dc:e6:af:48:a0:3b:bf:d2:5e:8c:d0: 36:41:41Cofactor: 1 (0x1)
6) 命令行举例
常规做法可能是执行./brainwallet $(sha256sum myphoto | sed -e "s/\([^ ]*\)[ ]*.*/\1/g")
localhost ~ # ./brainwallet $(sha256sum testfile | sed -e "s/\([^ ]*\)[ ]*.*/\1/g")Private-Key: (256 bit)priv: 2c:f2:4d:ba:5f:b0:a3:0e:26:e8:3b:2a:c5:b9:e2: 9e:1b:16:1e:5c:1f:a7:42:5e:73:04:33:62:93:8b: 98:24pub: 04:87:d8:20:42:d9:34:47:00:8d:fe:2a:f7:62:06: 8a:1e:53:ff:39:4a:5b:f8:f6:8a:04:5f:a6:42:b9: 9e:a5:d1:53:f5:77:dd:2d:ba:6c:7a:e4:cf:d7:b6: 62:24:09:d7:ed:d2:d7:6d:d1:3a:80:92:cd:3a:f9: 7b:77:bd:2c:77Field Type: prime-fieldPrime: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:fe:ff: ff:fc:2fA: 0B: 7 (0x7)Generator (uncompressed): 04:79:be:66:7e:f9:dc:bb:ac:55:a0:62:95:ce:87: 0b:07:02:9b:fc:db:2d:ce:28:d9:59:f2:81:5b:16: f8:17:98:48:3a:da:77:26:a3:c4:65:5d:a4:fb:fc: 0e:11:08:a8:fd:17:b4:48:a6:85:54:19:9c:47:d0: 8f:fb:10:d4:b8Order: 00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:fe:ba:ae:dc:e6:af:48:a0:3b:bf:d2:5e:8c:d0: 36:41:41Cofactor: 1 (0x1)
localhost ~ # echo -n $(sha256sum testfile | sed -e "s/\([^ ]*\)[ ]*.*/\1/g")2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
localhost ~ # cat testfile hello
7) 对比和提示
和js语言的在线版本对比(算法是一次SHA256)
得到你的比特币收款地址
脑钱包的原理大致如此,但是各个脑钱包工具的生成算法可能各异的,比如有的是2此的sha256sum,有的是3次,有的是pad了一些数据。所以,这些工具不一定兼容,也可能导致的你的脑钱包丢失,如果在试图使用多个脑钱包,而不知道他的算法的话。
- 【比特币】脑钱包
- 比特币钱包
- 比特币在线钱包
- 比特币钱包地址
- 关于比特币钱包
- 比特币钱包怎么开发
- 比特币钱包官方下载
- 比特币学习之钱包
- 搭建比特币钱包 Copay
- 解读比特币官方钱包加解密
- 一种比特币冷钱包的解决方案
- 解读比特币官方钱包加解密
- BTC比特币钱包性能优化
- 比特币中分层钱包问题
- 比特币钱包地址生成算法
- 比特币及钱包的基础知识
- 比特币钱包BitPay使用教程
- 比特币开发专题(比特币钱包功能介绍)
- 常见算法在实际项目中的应用
- 【raviramamoorthi-Computer Graphics】OpenGL1:Drawing
- 生活就是会开一些不经意的玩笑,给你转个弯,绊个道,然后给你不一样的视角。有些人很幸运发现了,有些人一辈子在无视。然后忆往昔,恨当下。把一切都怪给命运。
- Activity简介
- 年轻工程师为何只能卖个“白菜价”?
- 【比特币】脑钱包
- Hibernate查询之list/iterator
- MYSQL数据库引擎分析
- 字符串匹配算法总结
- 黑马程序员——结构体
- Visual Studio 2013开发 mini-filter driver step by step 应用层与内核通讯(8)
- mysql之union联合查询、子查询、连接查询
- 一小段代码演示C#接口的类级别实现和显式接口成员实现
- 程序语言基础知识总结