Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中使用ecdsa签名和验证签名_Python_Ecdsa - Fatal编程技术网

如何在python中使用ecdsa签名和验证签名

如何在python中使用ecdsa签名和验证签名,python,ecdsa,Python,Ecdsa,我需要使用256位的私钥为ECDSA的256位散列签名,就像比特币一样。由于缺少python中的ECDSA文档,我感到绝望 我在互联网上找到了很多代码,但没有什么比ecdsa.sign(msg,privkey)或类似的代码更简单的了,我发现的所有东西都是我不懂的数学代码,但他们使用ecdsa库(我不知道他们为什么不在一个库中添加一个签名函数来签名,而在使用库时需要一页代码?) 这是迄今为止我发现的最好的代码: def ecdsa_sign(val, secret_exponent): "

我需要使用256位的私钥为ECDSA的256位散列签名,就像比特币一样。由于缺少python中的ECDSA文档,我感到绝望

我在互联网上找到了很多代码,但没有什么比ecdsa.sign(msg,privkey)或类似的代码更简单的了,我发现的所有东西都是我不懂的数学代码,但他们使用ecdsa库(我不知道他们为什么不在一个库中添加一个签名函数来签名,而在使用库时需要一页代码?)

这是迄今为止我发现的最好的代码:

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()
def ecdsa_符号(val,secret_指数):
“”“使用提供的
随机时间。随机时间是不可预测的,这是绝对重要的
范围为[1,self.public_key.point.order()-1]的数字。如果
攻击者可以随机猜测,他可以从
单个签名。另外,如果攻击者知道一些高阶
位(或一些低阶位)的随机数,他可以计算出我们的私有数据
来自多个签名的密钥。具有足够
加密强度非常困难,远远超出范围
对这一评论的评论。
可能会引发RuntimeError,在这种情况下,请使用新的
随机值k是有序的。
"""
G=ecdsa.SECP256k1
n=G.订单()
k=确定性生成(n,秘密指数,val)
p1=k*G
r=p1.x()
如果r==0:raise RUNTIMERROR(“非常不幸的随机数r”)
s=(ecdsa.numbertheory.inverse_mod(k,n)*(val+(秘密指数*r)%n))%n
如果s==0:raise RUNTIMERROR(“非常不幸的随机数s”)
将签名返回到订单(r,s)
def definistic_generate_k(生成器顺序、秘密指数、val、hash_f=hashlib.sha256):
"""
根据生成K值https://tools.ietf.org/html/rfc6979
"""
n=发电机\u顺序
顺序大小=(位长度(n)+7)//8
hash\u size=hash\u f()。摘要大小
v=b'\x01'*散列大小
k=b'\x00'*散列大小
priv=intbytes.to_字节(秘密指数,长度=顺序大小)
shift=8*散列大小-位长度(n)
如果shift>0:
val>>=移位
如果val>n:
val-=n
h1=整数字节。到字节(val,长度=订单大小)
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()
而1:
t=bytearray()
而透镜(t)<订单尺寸:
v=hmac.new(k,v,hash_f).digest()
t、 扩展(v)
k1=整数字节。从_字节(字节(t))
k1>>=(长度(t)*8位长度(n))
如果k1>=1且k1
但是我不能相信这样的代码,因为我不知道它是做什么的。另外,ecdsa_sign中的注释说,给定值,和一个nonce,它返回一个签名。它说有一个nonce非常重要,但我就是不知道该nonce在哪里


在windows上使用python中的任何可信库,是否有任何简单的单行方式来签名和验证ECDSA签名?

您可以尝试使用python ECDSA包,使用Python3:

pip3 install ecdsa
用法:

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
要使用公钥验证现有签名,请执行以下操作:

import ecdsa
from hashlib import sha256
message = b"message"
public_key = '98cedbb266d9fc38e41a169362708e0509e06b3040a5dfff6e08196f8d9e49cebfb4f4cb12aa7ac34b19f3b29a17f4e5464873f151fd699c2524e0b7843eb383'
sig = '740894121e1c7f33b174153a7349f6899d0a1d2730e9cc59f674921d8aef73532f63edb9c5dba4877074a937448a37c5c485e0d53419297967e95e9b1bef630d'

vk = ecdsa.VerifyingKey.from_string(bytes.fromhex(public_key), curve=ecdsa.SECP256k1, hashfunc=sha256) # the default is sha1
vk.verify(bytes.fromhex(sig), message) # True

该软件包也与Python 2兼容

您还可以使用Python中的sep256k1库对ecdsa进行签名和验证。公钥和私钥是根据Bip32规范生成的密钥,也是根据Bip39规范生成的种子

 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
根据验证结果,结果将为真或假。 我使用uint32(键入)或int作为nonce,但可以使用任何字节数组或字符串。字符串需要转换为字节。

如何安装它:

pip安装starkbank ecdsa

如何使用它:

#生成密钥
privateKey=privateKey()
publicKey=privateKey.publicKey()
message=“我的测试消息”
#生成签名
签名=Ecdsa.sign(消息,私钥)
#验证签名是否有效
打印Ecdsa。验证(消息、签名、公钥)

完整参考资料:

您不能使用openssl进行签名吗?使用openssl优于ecdsa的优点是什么?我想ecdsa库使用openssl没有区别,您可以使用openssl访问任何需要的内容。我同意您不必编写像示例中的代码那样详细的代码来使用ecdsa。您看到了吗这个Python ECDSA库?您也可以对摘要数据使用sign_digest和verify_digest,例如,如果您正在以二进制形式传递sha256散列。有没有办法使密钥更小?例如,定义它们的最大大小?@k26dr Thank You.Dang!我正在将其用于区块链……我已经写了足够多的代码来确保区块链工作它只是没有公钥验证。没有空间容纳这么长的公钥…所以现有的区块链是垃圾。哦,哈哈。@Nuclear\u Man\D如果你是说这个例子生成的公钥对于区块链来说太长,那么你是对的。这就是为什么比特币对公钥做了一些额外的事情!小错误。需要
导入ec两个示例中的dsa
名称错误:未定义名称“ecdsa”
将引发错误。