Tengo que firmar un hash de 256 bits con ECDSA el uso de una clave privada de 256 bits, así como bitcoin hace, y estoy llegando a la desesperación por la falta de documentación de ecdsa en python.

He encontrado un montón de códigos en internet, pero no hay nada tan fácil como ecdsa.sign(msg, privkey) o similar, todo lo que he encontrado es un montón de código de matemática cosas que no entiendo, pero, sin embargo, el uso de la firma ecdsa de la biblioteca (no sé por qué no agregar una firma en función de una biblioteca que va a ser utilizado para firmar cosas, en lugar de una página de código es necesaria cuando se utiliza la biblioteca?).

Este es el mejor código que he encontrado hasta ahora:

def ecdsa_sign(val, secret_exponent):
"""Return a signature for the provided hash, using the provided
random nonce. It is absolutely vital that random_k be an unpredictable
number in the range [1, self.public_key.point.order()-1].  If
an attacker can guess random_k, he can compute our private key from a
single signature. Also, if an attacker knows a few high-order
bits (or a few low-order bits) of random_k, he can compute our private
key from many signatures. The generation of nonces with adequate
cryptographic strength is very difficult and far beyond the scope
of this comment.
May raise RuntimeError, in which case retrying with a new
random value k is in order.
"""
G = ecdsa.SECP256k1
n = G.order()
k = deterministic_generate_k(n, secret_exponent, val)
p1 = k * G
r = p1.x()
if r == 0: raise RuntimeError("amazingly unlucky random number r")
s = ( ecdsa.numbertheory.inverse_mod( k, n ) * ( val + ( secret_exponent * r ) % n ) ) % n
if s == 0: raise RuntimeError("amazingly unlucky random number s")
return signature_to_der(r, s)
def deterministic_generate_k(generator_order, secret_exponent, val, hash_f=hashlib.sha256):
"""
Generate K value according to https://tools.ietf.org/html/rfc6979
"""
n = generator_order
order_size = (bit_length(n) + 7) // 8
hash_size = hash_f().digest_size
v = b'\x01' * hash_size
k = b'\x00' * hash_size
priv = intbytes.to_bytes(secret_exponent, length=order_size)
shift = 8 * hash_size - bit_length(n)
if shift > 0:
val >>= shift
if val > n:
val -= n
h1 = intbytes.to_bytes(val, length=order_size)
k = hmac.new(k, v + b'\x00' + priv + h1, hash_f).digest()
v = hmac.new(k, v, hash_f).digest()
k = hmac.new(k, v + b'\x01' + priv + h1, hash_f).digest()
v = hmac.new(k, v, hash_f).digest()
while 1:
t = bytearray()
while len(t) < order_size:
v = hmac.new(k, v, hash_f).digest()
t.extend(v)
k1 = intbytes.from_bytes(bytes(t))
k1 >>= (len(t)*8 - bit_length(n))
if k1 >= 1 and k1 < n:
return k1
k = hmac.new(k, v + b'\x00', hash_f).digest()
v = hmac.new(k, v, hash_f).digest()

Pero yo simplemente no puede confiar en un código como el que porque no tengo idea de lo que hace. También, los comentarios en ecdsa_sign dice que devuelve una firma dado el valor, el secreto de la exponente, y un nonce. Se dice que es muy importante tener un nonce, pero no puedo averiguar dónde que nonce es.

Es allí cualquier simple, una línea de camino para firmar y verificar la firma ECDSA firmas con independencia de confianza de la biblioteca de python en windows?

no se puede firmar con openssl?
¿cuáles son las ventajas de usar openssl más de ecdsa?
Me imagino que el ecdsa lib utiliza openssl, por lo que no hay diferencia, usted tendrá acceso a todo lo que necesitas usando openssl openssl.org/docs/manmaster/crypto/ecdsa.html guyrutenberg.com/2013/12/28/…
Yo estaría de acuerdo en que usted no debería tener que escribir código como se detalla como el código en el ejemplo que acabo de utilizar ECDSA. Has visto Python ECDSA de la biblioteca? github.com/warner/python-ecdsa

OriginalEl autor Jorky10 | 2015-12-24

2 Comentarios

  1. 16

    Puede intentar usar el python ecdsa paquete, utilizando Python3:

    pip3 install ecdsa

    Uso:

    import ecdsa
    # SECP256k1 is the Bitcoin elliptic curve
    sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) 
    vk = sk.get_verifying_key()
    sig = sk.sign(b"message")
    vk.verify(sig, b"message") # True

    Para verificar una firma existentes con una clave pública:

    import ecdsa
    message = b"message"
    public_key = '98cedbb266d9fc38e41a169362708e0509e06b3040a5dfff6e08196f8d9e49cebfb4f4cb12aa7ac34b19f3b29a17f4e5464873f151fd699c2524e0b7843eb383'
    sig = '740894121e1c7f33b174153a7349f6899d0a1d2730e9cc59f674921d8aef73532f63edb9c5dba4877074a937448a37c5c485e0d53419297967e95e9b1bef630d'
    vk = ecdsa.VerifyingKey.from_string(bytes.fromhex(public_key), curve=ecdsa.SECP256k1)
    vk.verify(bytes.fromhex(sig), message) # True

    El paquete es compatible con Python 2 así

    También puede utilizar sign_digest y verify_digest digeridos de datos, por ejemplo, si se pasa un valor de hash sha256 en binario.
    Hay alguna forma de hacer que las teclas más pequeñas? Por ejemplo, definir su tamaño máximo?
    Creo que el tamaño de la clave es fijo.
    Gracias. Dang! La estoy usando para una blockchain…. Y ya he escrito suficiente como para que el blockchain obras no sólo la validación de clave pública. No hay espacio para un largo tiempo de clave pública…, por Lo que el blockchain es basura. Oh bien, lol.
    si te refieres a que la clave pública de este ejemplo se genera es demasiado largo para el Blockchain, entonces usted está en lo correcto. es por eso que Bitcoin tiene algunas cosas extras con la clave pública!

    OriginalEl autor k26dr

  2. 0

    también puede utilizar sep256k1 de la biblioteca de Python para ecdsa firmar y verificar. Las claves pública y privada de las claves generadas a partir Bip32 especificaciones y semillas de Bip39 especificaciones.

     Private key  is  1149ab92fbc40993f21336206ca184a9dc2d5231eb575d2a0a6d56773bf0f356
    Public key  is  03c7ac999403591bceacca3d37598886f7c41943c8045c7e1cb5a9295d0003cc5b
    from sawtooth_signing.secp256k1 import Secp256k1PrivateKey
    from sawtooth_signing.secp256k1 import Secp256k1PublicKey
    def sign_nonce(hex_private_key):
    nonce = random.randint(2**10, 2**32)
    checksum = hashlib.sha3_512(str(nonce).encode()).hexdigest()
    private_key = Secp256k1PrivateKey.from_hex(hex_private_key)
    message = private_key.secp256k1_private_key.ecdsa_sign(str(nonce).encode())
    serialized_message = private_key.secp256k1_private_key.ecdsa_serialize(message)
    hex_message = binascii.hexlify(serialized_message)
    return nonce, checksum, hex_message
    def verify_nonce(nonce, checksum, message, hex_public_key):
    ##message is hex encoded
    message = binascii.unhexlify(message)
    public_key = Secp256k1PublicKey.from_hex(hex_public_key)
    unserialized = public_key.secp256k1_public_key.ecdsa_deserialize(message)
    result = public_key.secp256k1_public_key.ecdsa_verify(str(nonce).encode(),    unserialized)
    return result

    El resultado será True o False dependiendo de la verificación.
    he utilizado uint32(tipificaciones) o int como un nonce, pero cualquier byte de la matriz o de la cadena puede ser utilizado. las cadenas deben ser convertidos a bytes.

    OriginalEl autor GraphicalDot

Dejar respuesta

Please enter your comment!
Please enter your name here