Kuidas luua teie enda Bitcoini privaatvõti

Krüptovaluutades lubab privaatvõti kasutajal juurdepääsu oma rahakotile. Privaatset võtit omav isik kontrollib selle rahakoti münte täielikult. Sel põhjusel peaksite seda saladuses hoidma. Ja kui soovite võtit ise genereerida, on mõistlik see turvaliselt genereerida.

Siinkohal teen sissejuhatuse privaatvõtmetesse ja näitan teile, kuidas saate oma võtit erinevate krüptofunktsioonide abil genereerida. Esitan Pythoni algoritmi ja koodi kirjelduse.

Kas ma pean genereerima privaatvõtme?

Enamasti seda ei tehta. Näiteks kui kasutate veebifotot nagu Coinbase või Blockchain.info, loovad ja haldavad nad teie jaoks privaatset võtit. Sama on vahetustega.

Mobiil- ja lauaarvutite rahakotid genereerivad tavaliselt ka teie jaoks privaatvõtme, ehkki neil võib olla võimalus luua rahakott oma privaatvõtmest.

Miks siis seda ikkagi luua? Minu põhjused on järgmised:

  • Tahad veenduda, et keegi ei tea võtit
  • Soovite lihtsalt rohkem teada saada krüptograafia ja juhuslike arvude genereerimise (RNG) kohta

Mis täpselt on privaatvõti?

Formaalselt on Bitcoini (ja paljude teiste krüptovaluutade) privaatvõti 32-baidine jada. Nüüd on nende baitide salvestamiseks palju võimalusi. See võib olla 256-st ja nullist (32 * 8 = 256) või 100 täringurullist koosnev string. See võib olla binaarne string, Base64 string, WIF-võti, mnemooniline fraas või lõpuks kuusnurk. Meie eesmärkidel kasutame 64 tähemärki pikkust kuusnurka.

Sama privaatvõti, kirjutatud erinevates vormingutes.

Miks täpselt 32 baiti? Suurepärane küsimus! Näete, et privaatse võtme loomiseks kasutab Bitcoin ECDSA või Elliptic Curve Digital Signature Algorithm. Täpsemalt, see kasutab ühte kindlat kõverat, mida nimetatakse secp256k1.

Nüüd on selle kõvera suurusjärk 256 bitti, sisendiks võetakse 256 bitti ja väljundiks on 256-bitised täisarvud. Ja 256 bitti on täpselt 32 baiti. Ehk siis teisiti öeldes on selle kõvera algoritmi jaoks vaja 32 baiti andmeid.

Privaatvõtme jaoks on olemas täiendav nõue. Kuna kasutame ECDSA, peaks võti olema positiivne ja olema väiksem kui kõvera järjekord. Järjestus secp256k1 on FFFFFFFFFFFFFFFFFFFFFFFFFFFBABAAEDCE6AF48A03BBFD25E8CD0364141, mis on päris suur: peaaegu iga 32-baidine arv on sellest väiksem.

Naiivne meetod

Niisiis, kuidas luua 32-baidine täisarv? Esimene asi, mis pähe tuleb, on lihtsalt kasutada RNG teeki teie valitud keeles. Python pakub isegi armsat viisi piisava arvu bittide genereerimiseks:

import juhuslikult
bitti = random.getrandbits (256)
# 30848827712021293731208415302456569301499384654877289245795786476741155372082
bits_hex = heks (bitti)
# 0x4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32
private_key = bits_hex [2:]
# 4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32

Näeb hea välja, aga tegelikult pole. Näete, tavalised RNG-teegid pole krüptograafiaks ette nähtud, kuna need pole eriti turvalised. Nad genereerivad numbreid seemne põhjal ja vaikimisi on seeme praegune aeg. Nii saate teada, kui ma ülaltoodud bitid genereerisin, vaid peate mõned variandid sundima.

Privaatvõtme genereerimisel soovite olla eriti turvaline. Pidage meeles, et kui keegi õpib privaatset võtit, saab ta kõik mündid vastavalt rahakotilt hõlpsasti varastada ja teil pole võimalust neid kunagi tagasi saada.

Proovime seda teha kindlamini.

Krüptograafiliselt tugev RNG

Koos standardse RNG-meetodiga pakuvad programmeerimiskeeled tavaliselt RNG-d, mis on spetsiaalselt ette nähtud krüptograafilisteks toiminguteks. See meetod on tavaliselt palju turvalisem, kuna see tõmbab entroopia otse opsüsteemist. Sellise RNG tulemust on palju raskem taasesitada. Te ei saa seda teha, teades põlvnemise aega või omades seemet, sest seemet pole. Noh, vähemalt kasutaja ei sisesta seemet - pigem on see loodud programmi poolt.

Pythonis rakendatakse saladuste moodulis krüptograafiliselt tugev RNG. Muutkem ülaltoodud koodi, et privaatvõtme genereerimine oleks turvaline!

impordisaladused
bitti = saladusi.ribbitid (256)
# 46518555179467323509970270980993648640987722172281263586388328188640792550961
bits_hex = heks (bitti)
# 0x66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31
private_key = bits_hex [2:]
# 66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31

See on imeline. Vean kihla, et te ei saaks seda isegi minu arvutile juurdepääsu korral korrata. Kuid kas me võime minna sügavamale?

Spetsialiseeritud saidid

On saite, mis genereerivad teile juhuslikke numbreid. Vaatleme siin ainult kahte. Üks on random.org, tuntud üldotstarbeline juhuslike arvude generaator. Teine on bitaddress.org, mis on loodud spetsiaalselt Bitcoini privaatvõtme genereerimiseks.

Kas random.org aitab meil võtit luua? Kindlasti, kuna neil on juhuslike baitide genereerimise teenus. Kuid siin kerkib esile kaks probleemi. Random.org väidab end olevat tõeliselt juhuslik generaator, kuid kas saate seda usaldada? Kas võite olla kindel, et see on tõepoolest juhuslik? Kas võite olla kindel, et omanik ei salvesta kõiki põlvkonna tulemusi, eriti neid, mis näevad välja nagu privaatvõtmed? Vastus on teie enda otsustada. Ja te ei saa seda lokaalselt käivitada, mis on täiendav probleem. See meetod pole 100% turvaline.

Nüüd on bitaddress.org hoopis teine ​​lugu. See on avatud lähtekoodiga, nii et näete, mis selle kapoti all on. See on kliendi poolel, nii et saate selle alla laadida ja kohapeal käitada, isegi ilma Interneti-ühenduseta.

Kuidas see siis töötab? See kasutab sind - jah, sind - entroopia allikana. See palub teil hiirt liigutada või vajutada juhuslikke klahve. Teete seda piisavalt kaua, et tulemuste reprodutseerimine oleks võimatu.

Entroopia genereerimise protsess hiire juhusliku liigutamise teel. Suur sümbolite tükk näitab basseini.

Kas olete huvitatud, kuidas bitaddress.org töötab? Hariduslikel eesmärkidel vaatame selle koodi ja proovime seda Pythonis korrata.

Kiire märkus: bitaddress.org annab teile privaatvõtme tihendatud WIF-vormingus, mis on lähedane WIF-vormingule, millest me varem arutasime. Meie eesmärkidel saadame algoritmi tagasi kuusnurga stringi, et saaksime seda hiljem avaliku võtme genereerimiseks kasutada.

Bitdress: eripära

Bitaddress loob entroopia kahel kujul: hiire liikumise ja klahvi rõhu abil. Me räägime mõlemast, kuid keskendume klahvide vajutustele, kuna Pythoni libisloos on raske hiire jälgimist rakendada. Eeldame, et lõppkasutaja kirjutab nuppe, kuni entroopia on piisavalt suur, ja siis genereerime võtme.

Bitaddress teeb kolme asja. See lähtestab baitimassiivi, proovides arvutist võimalikult palju entroopiat saada, täidab massiivi kasutaja sisendiga ja genereerib siis privaatvõtme.

Bitaddress kasutab entroopia salvestamiseks 256-baidist massiivi. See massiiv kirjutatakse ümber tsüklitena, nii et kui massiivi esmakordselt täita, läheb kursor nulli ja täitmisprotsess algab uuesti.

Programm algatab akna.crypto 256 baitise massiivi. Seejärel kirjutab ta ajatemperatuuri, et saada täiendavat 4 baiti entroopiat. Lõpuks saab see selliseid andmeid nagu ekraani suurus, teie ajavöönd, teave brauseri pistikprogrammide, teie lokaadi ja muu kohta. See annab veel 6 baiti.

Pärast lähtestamist ootab programm pidevalt kasutaja sisendit algsete baitide ümberkirjutamiseks. Kui kasutaja kursorit liigutab, kirjutab programm kursori asukoha. Kui kasutaja nuppe vajutab, kirjutab programm vajutatud nupu char-koodi.

Lõpuks kasutab bitaddress privaatvõtme genereerimiseks akumuleeritud entroopiat. See peab genereerima 32 baiti. Selle ülesande jaoks kasutab bitaddress RNG algoritmi nimega ARC4. Programm lähtestab ARC4 praeguse ajaga ja kogutud entroopiaga, seejärel saab baite ükshaaval 32 korda.

See kõik on programmi toimimise lihtsustamine, kuid ma loodan, et saate selle idee. Githubis saate algoritmi üksikasjalikult kontrollida.

Tehes seda ise

Oma eesmärkidel ehitame bitadressi lihtsama versiooni. Esiteks ei kogu me andmeid kasutaja masina ja asukoha kohta. Teiseks sisestame entroopia ainult teksti kaudu, kuna Pythoni skripti abil on pidevalt keeruline hiire asukohta vastu võtta (kui soovite seda teha, kontrollige PyAutoGUI).

See viib meid generaatori raamatukogu ametliku spetsifikatsioonini. Esiteks lähtestab see baitmassiivi krüptograafilise RNG-ga, siis täidab see ajatempli ja lõpuks täidab selle kasutaja loodud stringi. Pärast seemnevarude täitmist laseb raamatukogu arendajal võtme luua. Tegelikult on nad võimelised looma nii palju privaatvõtmeid, kui nad tahavad, ja kõik need on tagatud kogutud entroopiaga.

Basseini käivitamine

Panime siia mõned baitid krüptograafilisest RNG-st ja ajatempel. __seed_int ja __seed_byte on kaks abimeetodit, mis sisestavad entroopia meie basseinimassiivi. Pange tähele, et kasutame saladusi.

def __init_pool (ise):
    minu jaoks vahemikus (ise.POOL_SIZE):
        random_byte = secrets.randbits (8)
        ise .__ seeme_byte (juhuslik_byte)
    time_int = int (aeg.time ())
    ise .__ seemet_int (aeg_int)
def __seed_int (ise, n):
    ise .__ seeme_byte (n)
    ise .__ seeme_byte (n >> 8)
    ise .__ seeme_byte (n >> 16)
    ise .__ seeme_byte (n >> 24)
def __seed_byte (ise, n):
    self.pool [self.pool_pointer] ^ = n & 255
    self.pool_pointer + = 1
    kui self.pool_pointer> = self.POOL_SIZE:
        self.pool_pointer = 0

Külvamine sisendiga

Panime siia kõigepealt ajatempli ja seejärel sisestusstringi, märkide kaupa.

def seed_input (ise, str_input):
    time_int = int (aeg.time ())
    ise .__ seemet_int (aeg_int)
    jaoks char in str_input:
        char_code = ord (char)
        ise .__ seemebait (char_code)

Privaatvõtme genereerimine

See osa võib tunduda raske, kuid tegelikult on see väga lihtne.

Esiteks peame oma kogumi abil genereerima 32-baidise arvu. Kahjuks ei saa me lihtsalt luua oma juhuslikku objekti ja kasutada seda ainult võtmete genereerimiseks. Selle asemel on jagatud objekt, mida kasutab iga skriptis töötav kood.

Mida see meie jaoks tähendab? See tähendab, et igal hetkel, ükskõik kus koodis, võib üks lihtne random.seed (0) hävitada kogu meie kogutud entroopia. Me ei taha seda. Õnneks pakub Python gettate ja settate meetodeid. Seega, et päästa oma entroopia iga kord, kui võtit genereerime, mäletame seisundit, kus peatusime, ja panime selle järgmine kord klahvi valmistama.

Teiseks, lihtsalt veenduge, et meie võti oleks vahemikus (1, CURVE_ORDER). See on kohustus kõigi ECDSA privaatvõtmete jaoks. CURVE_ORDER on kõvera secp256k1 järjekord, mis on FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141.

Lõpuks teisendame mugavuse huvides heksiks ja ribad eemaldame osa „0x”.

def genereerimisklahv (ise):
    big_int = ise .__ genereerima_big_int ()
    big_int = big_int% (ise.CURVE_ORDER - 1) # klahv  0
    võti = kuusnurk (big_int) [2:]
    tagastamise võti
def __generate_big_int (ise):
    kui self.prng_state ei ole:
    seed = int.from_bytes (self.pool, byteorder = 'suur', allkirjastatud = False)
    random.seed (seeme)
    self.prng_state = random.getstate ()
    random.setstate (self.prng_state)
    big_int = random.getrandbits (ise.KEY_BYTES * 8)
    self.prng_state = random.getstate ()
    tagasi big_int

Tegevuses

Proovime teeki kasutada. Tegelikult on see väga lihtne: saate genereerida privaatvõtme kolmes koodireas!

kg = KeyGenerator ()
kg.seed_input ("Tõeliselt juhuslik string. Veeretasin täringut ja sain 4.")
kg.generate_key ()
# 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2

Saate seda ise näha. Võti on juhuslik ja täiesti kehtiv. Lisaks saate iga kord, kui selle koodi käivitate, teistsuguseid tulemusi.

Järeldus

Nagu näete, on privaatvõtmete genereerimiseks palju võimalusi. Need erinevad lihtsuse ja turvalisuse poolest.

Privaatvõtme genereerimine on alles esimene samm. Järgmine samm on avaliku võtme ja rahakotiaadressi eraldamine, mida saate kasutada maksete vastuvõtmiseks. Rahakoti genereerimise protsess erineb Bitcoini ja Ethereumi puhul ning plaanin kirjutada sellel teemal veel kaks artiklit.

Kui soovite koodiga mängida, avaldasin selle selles Githubi hoidlas.

Teen kursuse krüptovaluutade kohta siin keskkonnas. Esimene osa on plokiahela üksikasjalik kirjeldus.

Postitan Twitterisse ka juhuslikke mõtteid krüpto kohta, nii et võiksite seda kontrollida.