Wie sicher ist der von diesem Skript generierte private Bitcoin-Schlüssel? [geschlossen]

Ich habe dieses Python-Skript auf github gefunden .

Es generiert ein Paar aus privatem Bitcoin-Schlüssel und Adresse.

Ich weiß, dass der private Schlüssel anfällig sein kann, wenn er unsicher erstellt wird.

Ich habe nicht viel Wissen über Kryptologie. Können Sie überprüfen, ob das Skript sicher ist?

#!/usr/bin/env python
# Joric/bitcoin-dev, june 2012, public domain

import hashlib
import ctypes
import ctypes.util
import sys

ssl = ctypes.cdll.LoadLibrary (ctypes.util.find_library ('ssl') or 'libeay32')

def check_result (val, func, args):
    if val == 0: raise ValueError 
    else: return ctypes.c_void_p (val)

ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
ssl.EC_KEY_new_by_curve_name.errcheck = check_result

class KEY:
    def __init__(self):
        NID_secp256k1 = 714
        self.k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1)
        self.compressed = False
        self.POINT_CONVERSION_COMPRESSED = 2
        self.POINT_CONVERSION_UNCOMPRESSED = 4

def __del__(self):
    if ssl:
        ssl.EC_KEY_free(self.k)
    self.k = None

def generate(self, secret=None):
    if secret:
        self.prikey = secret
        priv_key = ssl.BN_bin2bn(secret, 32, ssl.BN_new())
        group = ssl.EC_KEY_get0_group(self.k)
        pub_key = ssl.EC_POINT_new(group)
        ctx = ssl.BN_CTX_new()
        ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx)
        ssl.EC_KEY_set_private_key(self.k, priv_key)
        ssl.EC_KEY_set_public_key(self.k, pub_key)
        ssl.EC_POINT_free(pub_key)
        ssl.BN_CTX_free(ctx)
        return self.k
    else:
        return ssl.EC_KEY_generate_key(self.k)

def get_pubkey(self):
    size = ssl.i2o_ECPublicKey(self.k, 0)
    mb = ctypes.create_string_buffer(size)
    ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb)))
    return mb.raw

def get_secret(self):
    bn = ssl.EC_KEY_get0_private_key(self.k);
    bytes = (ssl.BN_num_bits(bn) + 7) / 8
    mb = ctypes.create_string_buffer(bytes)
    n = ssl.BN_bn2bin(bn, mb);
    return mb.raw.rjust(32, chr(0))

def set_compressed(self, compressed):
    self.compressed = compressed
    if compressed:
        form = self.POINT_CONVERSION_COMPRESSED
    else:
        form = self.POINT_CONVERSION_UNCOMPRESSED
    ssl.EC_KEY_set_conv_form(self.k, form)

def dhash(s):
    return hashlib.sha256(hashlib.sha256(s).digest()).digest()

def rhash(s):
    h1 = hashlib.new('ripemd160')
    h1.update(hashlib.sha256(s).digest())
    return h1.digest()

b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def base58_encode(n):
    l = []
    while n > 0:
        n, r = divmod(n, 58)
        l.insert(0,(b58_digits[r]))
    return ''.join(l)

def base58_decode(s):
    n = 0
    for ch in s:
        n *= 58
        digit = b58_digits.index(ch)
        n += digit
    return n

def base58_encode_padded(s):
    res = base58_encode(int('0x' + s.encode('hex'), 16))
    pad = 0
    for c in s:
        if c == chr(0):
            pad += 1
        else:
            break
    return b58_digits[0] * pad + res

def base58_decode_padded(s):
    pad = 0
    for c in s:
        if c == b58_digits[0]:
            pad += 1
        else:
            break
    h = '%x' % base58_decode(s)
    if len(h) % 2:
        h = '0' + h
    res = h.decode('hex')
    return chr(0) * pad + res

def base58_check_encode(s, version=0):
    vs = chr(version) + s
    check = dhash(vs)[:4]
    return base58_encode_padded(vs + check)

def base58_check_decode(s, version=0):
    k = base58_decode_padded(s)
    v0, data, check0 = k[0], k[1:-4], k[-4:]
    check1 = dhash(v0 + data)[:4]
    if check0 != check1:
        raise BaseException('checksum error')
    if version != ord(v0):
        raise BaseException('version mismatch')
    return data

def gen_eckey(passphrase=None, secret=None, pkey=None, compressed=False, rounds=1, version=0):
    k = KEY()
    if passphrase:
        secret = passphrase.encode('utf8')
        for i in xrange(rounds):
            secret = hashlib.sha256(secret).digest()
    if pkey:
        secret = base58_check_decode(pkey, 128+version)
        compressed = len(secret) == 33
        secret = secret[0:32]
    k.generate(secret)
    k.set_compressed(compressed)
    return k

def get_addr(k,version=0):
    pubkey = k.get_pubkey()
    secret = k.get_secret()
    hash160 = rhash(pubkey)
    addr = base58_check_encode(hash160,version)
    payload = secret
    if k.compressed:
        payload = secret + chr(1)
    pkey = base58_check_encode(payload, 128+version)
    return addr, pkey

def reencode(pkey,version=0):
    payload = base58_check_decode(pkey,128+version)
    secret = payload[:-1]
    payload = secret + chr(1)
    pkey = base58_check_encode(payload, 128+version)
    print get_addr(gen_eckey(pkey))

def test(otherversion):
    # random compressed
    print get_addr(gen_eckey(compressed=True,version=otherversion),version=otherversion)

    # uncomment these to create addresses via a different method
    # random uncompressed
    #print get_addr(gen_eckey())
    # by secret
    #print get_addr(gen_eckey(secret=('%064x' % 0xdeadbabe).decode('hex')))
    # by passphrase
    #print get_addr(gen_eckey(passphrase='Satoshi Nakamoto'))
    # by private key
    #print get_addr(gen_eckey(pkey='5K1HkbYffstTZDuV4riUWMbAMkQh57b8798uoy9pXYUDYeUHe7F'))
    #print get_addr(gen_eckey(pkey='L3ATL5R9Exe1ubuAnHVgNgTKZEUKkDvWYAWkLUCyyvzzxRjtgyFe'))

    # uncomment this to reencode the private keys created by early versions of this script
    #reencode(sys.argv[1])

if __name__ == '__main__':
    import optparse
    parser = optparse.OptionParser(usage="%prog [options]")
    parser.add_option("--otherversion", dest="otherversion", default=0,
                    help="Generate address with different version number")
    (options, args) = parser.parse_args()

    test(int(options.otherversion))
crypto.stackexchange.com
Ich stimme dafür, diese Frage als nicht zum Thema gehörend zu schließen, da sie auf crypto.stackexchange.com gehört
Ich bin mir nicht sicher, ob nicht einmal crypto.SE der richtige Ort ist, um nach einer vollständigen Codeüberprüfung zu fragen, aber das gehört tatsächlich nicht zu bitcoin.SE, sorry

Antworten (1)

Wenn Sie nicht über die Möglichkeiten verfügen, dieses Skript im Detail zu überprüfen, sollten Sie zumindest untersuchen, wie weit verbreitet dieses Skript ist.

Ich würde empfehlen, es nicht zu verwenden.

Wenn Sie private Bitcoin-Schlüssel generieren möchten (und Bitcoin-Adressen aus dem entsprechenden öffentlichen Schlüssel erhalten), sollten Sie sich Bitcoin Core genau ansehen.

Wenn Sie nur Schlüssel und keinen Zugriff auf die Blockchain benötigen, können Sie die p2p-Interaktion mit deaktivieren -connect=0.

Bitcoin Core hat eine großartige RPC-Schnittstelle. Sie können weiterhin Python verwenden, um mit der API zu interagieren.

Vergessen Sie jedoch nicht, dass private Schlüssel stark von der Entropie Ihres Betriebssystems (Zufallszahlen) abhängen. Auch wenn Ihr System/Betriebssystem kompromittiert ist, sind Ihre Gelder, die Sie mit den auf diesem System generierten Schlüsseln erhalten haben, gefährdet.