Wenn ich eine kryptografische Signatur von einem Ethereum-Adressschlüsselpaar habe, wie kann ich diese Signatur verifizieren?
Solidity und Serpent haben ecrecover
zu diesem Zweck.
ecrecover(bytes32 data, uint8 v, bytes32 r, bytes32 s) gibt (Adresse) zurück
Die Funktionsargumente sind:
data
wurde unterschrieben . Da es sich um 32 Bytes handelt, bedeutet dies normalerweise, dass die anfänglichen Daten zuerst auf 32 Bytes gehasht werden, bevor sie signiert werden.
v
, r
, s
ist die Signatur. ( v
ist die Wiederherstellungs-ID: ein 1-Byte-Wert, der das Vorzeichen und die Endlichkeit des Kurvenpunkts angibt; dieser Wert liegt im Bereich von [27, 30], jedoch erklärt das Ethereum-Protokoll die oberen beiden Möglichkeiten, die unendliche Werte darstellen, für ungültig)
Wichtiger Hinweis zu den Beispielen unten, sha3 ist Keccak-256 .
Hier ist ein Ausschnitt in Solidity :
contract Auth {
function verify(address p, bytes32 hash, uint8 v, bytes32 r, bytes32 s) constant returns(bool) {
// Note: this only verifies that signer is correct.
// You'll also need to verify that the hash of the data
// is also correct.
return ecrecover(hash, v, r, s) == p;
}
}
Hier ist ein Beispiel in Serpent :
def test_ecrecover(h, v, r, s):
return(ecrecover(h, v, r, s))
Der entsprechende Testcode in Python (Requires bitcoin
und ethereum
Packages):
import bitcoin as b
from ethereum import tester, utils
class TestECRecover(object):
CONTRACT = """
def test_ecrecover(h, v, r, s):
return(ecrecover(h, v, r, s))
"""
def setup_class(cls):
cls.s = tester.state()
cls.c = cls.s.abi_contract(cls.CONTRACT)
cls.snapshot = cls.s.snapshot()
def setup_method(self, method):
self.s.revert(self.snapshot)
def test_ecrecover(self):
priv = b.sha256('some big long brainwallet password')
pub = b.privtopub(priv)
msghash = b.sha256('the quick brown fox jumps over the lazy dog')
V, R, S = b.ecdsa_raw_sign(msghash, priv)
assert b.ecdsa_raw_verify(msghash, (V, R, S), pub)
addr = utils.sha3(b.encode_pubkey(pub, 'bin')[1:])[12:]
assert utils.privtoaddr(priv) == addr
result = self.c.test_ecrecover(utils.big_endian_to_int(msghash.decode('hex')), V, R, S)
assert result == utils.big_endian_to_int(addr)
ecrecover
Verwendet unter der Haube den ECDSARECOVER
vorkompilierten Vertrag unter Adresse 1.
Hinweis: Geth und web3.eth.sign fügen der data
Nachricht vor dem Signieren ein Präfix hinzu.
Die Sign-Methode berechnet eine Ethereum-spezifische Signatur mit: sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))).
Durch das Hinzufügen eines Präfixes zur Nachricht wird die berechnete Signatur als Ethereum-spezifische Signatur erkennbar. Dies verhindert Missbrauch, bei dem eine böswillige DApp willkürliche Daten (z. B. Transaktionen) signieren und die Signatur verwenden kann, um sich als das Opfer auszugeben.
verify()
In diesem Fall muss das zweite Argument keccak256("\x19Ethereum Signed Message:\n", len(message), message)
anstelle von sein keccak256(message)
.
Verwandte: ecrecover von Geth und web3.eth.sign
JB
ryepdx
ZMitton
eth
sudo
Garen Vartanian