• Igor Pauer

(Ne)Bezpečnost v kryptoměnách Jak bezpečná je vaše peněženka?



Mnoho běžně používaných SW a HW peněženek obsahuje chyby, vyplývající

z neznalosti základních principů kryptografických algoritmů.


Dopředu se omlouvám za trochu odbornější článek, ale v poslední dobou se opakovaně setkávám (a to i u „odborníků“) s nedostatkem důsledných znalostí

o potencionálních záludnostech při práci s veřejnými/privátními klíči, blockchainovými adresami a hashovacími funkcemi.


Opravdu kvalitní odborník musí kromě programování ovládat i základy vysoké matematiky a šifrování, v opačném případě jeho práce může nevědomky obsahovat bezpečnostní chyby, v těch horších případech je „špatná práce“ odváděná záměrně.


Ukážeme si názorný příklad, jak lze dešifrovat privátní klíče v kryptografickém algoritmu ECDSA, pokud s ním nepracujeme správně.


Připomenu, že algoritmus ECDSA používá Bitcoin, zároveň je ECDSA schválený například NSA, pro obranu přísně tajných informací s velikosti klíče 384 bitů.


A přesto dále uvidíme, že při nesprávné práci je privátní klíče možné dešifrovat.

Předpokládejme, že Bob v ECDSA vytvoří náhodný privátní klíč (priv) a potom veřejný klíč.

pub = priv . G


Následně, aby vytvořil podpis zprávy M, vytvoří náhodné číslo (k) a vytvoří podpis:

r = k.G

s = k-1(H(M)+r.priv)


Podpis je následně (r,s), kde r je pozice bodu kG na ose x. H(M) je hash SHA-256 zprávy (M) konvertovaný na cele číslo (integer value).

V tomto případě bude mít Alice dva páry klíčů se dvěma privátními klíči (x1 a x2). Podepíše zprávu 1 (m1) a 3 (m3) prvním privátním klíčem (x1) a podepíše zprávu 2 (m2) a 4 (m4) druhým privátním klíčem (x2). Stejný nonce (k1) je použitý na podepsání zprávy 1 a 2 a další nonce (k2) je použitý na podepsání zprávy 3 a 4.

Takže máme čtyři zprávy (m1 az m4) a jejich hashe:


h1 = H(m1)

h2 = H(m2)

h3 = H(m3)

h4 = H(m4)


Podpisy pro jednotlivé zprávy budou: (s1,r1), (s2,r1), (s3,r2), a (s4,r2)


s1 = k1−1(h1+r1⋅x1)(modp)

s2 = k1−1(h2+r1⋅x2)(modp)

s3 = k2−1(h3+r2⋅x1)(modp)

s4 = k2−1(h4+r2⋅x2)(modp)



Použitím Gaussové eliminace se pak dají vypočítat privátní klíče:




a




Vzor kódu pro vypočet privátních klíčů v dané situaci:

import ecdsa

import random

import libnum

import hashlib

import sys


G = ecdsa.SECP256k1.generator

order = G.order()


priv1 = random.randrange(1,order)

Public_key = ecdsa.ecdsa.Public_key(G, G * priv1)

x1 = ecdsa.ecdsa.Private_key(Public_key, priv1)


priv2 = random.randrange(1,order)

Public_key2 = ecdsa.ecdsa.Public_key(G, G * priv2)

x2 = ecdsa.ecdsa.Private_key(Public_key2, priv2)


k1 = random.randrange(1, 2**127)

k2 = random.randrange(1, 2**127)


msg1="Sprava1"

msg2="Sprava2"

msg3="Sprava3"

msg4="Sprava4"


if (len(sys.argv)>1):

msg1=(sys.argv[1])

if (len(sys.argv)>2):

msg2=(sys.argv[2])

if (len(sys.argv)>3):

msg3=(sys.argv[3])

if (len(sys.argv)>4):

msg4=(sys.argv[4])


h1 = int(hashlib.sha256(msg1.encode()).hexdigest(),base=16)

h2 = int(hashlib.sha256(msg2.encode()).hexdigest(),base=16)

h3 = int(hashlib.sha256(msg3.encode()).hexdigest(),base=16)

h4 = int(hashlib.sha256(msg4.encode()).hexdigest(),base=16)

sig1 = x1.sign(h1, k1)

sig2 = x2.sign(h2, k1)

sig3 = x1.sign(h3, k2)

sig4 = x2.sign(h4, k2)


r1,s1 = sig1.r,sig1.s

r1_1,s2 = sig2.r,sig2.s

r2,s3 = sig3.r,sig3.s

r2_1,s4 = sig4.r,sig4.s


valinv = libnum.invmod( r1*r2*(s1*s4-s2*s3),order)


x1rec = ((h1*r2*s2*s3-h2*r2*s1*s3-h3*r1*s1*s4+h4*r1*s1*s3 ) * valinv) % order


x2rec = ((h1*r2*s2*s4-h2*r2*s1*s4-h3*r1*s2*s4+h4*r1*s2*s3 ) * valinv) % order


print ("\nSprava 1: ",msg1)

print (f"Signature r={r1}, s={s1}")

print ("\nSprava 2: ",msg2)

print (f"Signature r={r1_1}, s={s2}")

print ("\nSprava 3: ",msg3)

print (f"Signature r={r2}, s={s3}")

print ("\nSprava 4: ",msg4)

print (f"Signature r={r2_1}, s={s4}")


print ("\nPrivate key (x1):",priv1)

print ("\nPrivate recovered (x1): ",x1rec)

print ("\nPrivate key (x2):",priv2)

print ("\nPrivate recovered (x2):",x2rec)


Co dodat závěrem? Vzhledem k faktu, že operace s kryptoměnami a nad blockchainem, jsou už ze svého principu nezvratné, je dobré práci s nimi rozumět.


V opačném případě je rozumnější, obrátit se na odborníky a nespoléhat se slepě na funkčnost různých nabízených neznámých peněženek bez toho, abychom znali jejich tvůrce.


Nakonec dalším dost podstatným principem kryptoměn je osobní zodpovědnost, kterou jsme si v mnoha rovinách našeho života zvykli přenášet na někoho jiného.


Pokud v kryptosvětě uděláte chybu, může vás vyjít draho, protože je jedině vaše a nikdo jí za vás nemůže opravit nebo napravit.


Takže, jste dostatečně zodpovědní na to mít kryptoměny?