大蟒蛇python教程共享如何在python中实现ECDSA你知道吗

  import six  import timeit#查找任何特定代码执行的确切时间  from ecdsa.curves import curves  

  #定义do函数,计算时间  def do(setup_statements, statement):      # extracted from timeit.py      t = timeit.timer(stmt=statement, setup="n".join(setup_statements))      # determine number so that 0.2 <= total time < 2.0      for i in range(1, 10):          number = 10 ** i #**为次方          x = t.timeit(number)          if x >= 0.2:              break      return x / number  

nist为数字测试套件关于nist详解

gf§ (素数域)曲线,密钥长度为192、224、256、384和521bit

openssl工具(openssl ecparam -list_curves)所知道的这些曲线的 “简称 “是:prime192v1secp224r1prime256v1secp384r1secp521r1。它包括比特币使用的256位曲线secp256k1。它还支持160到512位的brainpool曲线的常规(非扭曲)变体。这些曲线的 “简称 “是:brainpoolp160r1, brainpoolp192r1, brainpoolp224r1, brainpoolp256r1, brainpoolp320r1, brainpoolp384r1, brainpoolp512r1。少数来自sec标准的小曲线也包括在内(主要是为了加快库的测试),它们是:secp112r1, secp112r2, secp128r1, 和secp160r1。没有包括其他的曲线,但要增加对更多素数域的曲线的支持并不难。

  #不是很懂 sep=":",unit="s",form=".5f",form_inv=".2f",  prnt_form = (      "{name:>16}{sep:1} {siglen:>6} {keygen:>9{form}}{unit:1} "      "{keygen_inv:>9{form_inv}} {sign:>9{form}}{unit:1} "      "{sign_inv:>9{form_inv}} {verify:>9{form}}{unit:1} "      "{verify_inv:>9{form_inv}} {verify_single:>13{form}}{unit:1} "      "{verify_single_inv:>14{form_inv}}"  )  print(      prnt_form.format(          siglen="siglen",          keygen="keygen",          keygen_inv="keygen/s",          sign="sign",          sign_inv="sign/s",          verify="verify",          verify_inv="verify/s",          verify_single="no pc verify",          verify_single_inv="no pc verify/s",          name="",          sep="",          unit="",          form="",          form_inv="",      )  )  for curve in [i.name for i in curves]:      s1 = "import six; from ecdsa import signingkey, %s" % curve      s2 = "sk = signingkey.generate(%s)" % curve #产生私钥      s3 = "msg = six.b('msg')" #消息      s4 = "sig = sk.sign(msg)" #签名      s5 = "vk = sk.get_verifying_key()"#公钥由私钥得出  get_verifying_key()函数      s6 = "vk.precompute()"#不懂      s7 = "vk.verify(sig, msg)"#用公钥验证签名      # 我们碰巧知道.generate()也在计算验证密钥,这是最耗时的部分。如果将代码改为懒惰地计算vk,我们就需要将这个基准改为在s5上循环,而不是在s2上。      keygen = do([s1], s2)      sign = do([s1, s2, s3], s4)      verf = do([s1, s2, s3, s4, s5, s6], s7)      verf_single = do([s1, s2, s3, s4, s5], s7)      import ecdsa      c = getattr(ecdsa, curve)#从免费精选名字大全上看获取属性值      sig = ecdsa.signingkey.generate(c).sign(six.b("msg"))      #密钥对(keygen)、签署数据(sign)、验证这些签名(verify)、共享秘密(ecdh)以及在没有特定密钥预计算的情况下验证签名(no pc verify)、原始签名的大小(通常是签名可以被编码的最小方式)也在siglen栏中提供      print(          prnt_form.format(              name=curve,#所有的曲线              sep=":",              siglen=len(sig),              unit="s",              keygen=keygen,              keygen_inv=1.0 / keygen,              sign=sign,              sign_inv=1.0 / sign,              verify=verf,              verify_inv=1.0 / verf,              verify_single=verf_single,              verify_single_inv=1.0 / verf_single,              form=".5f",#小数点后面为5位              form_inv=".2f",#小数点后面为2位          )      )  

  print("")  

ed25519和cureve5519

  ecdh_form = "{name:>16}{sep:1} {ecdh:>9{form}}{unit:1} {ecdh_inv:>9{form_inv}}"  print(      ecdh_form.format(          ecdh="ecdh",          ecdh_inv="ecdh/s",          name="",          sep="",          unit="",          form="",          form_inv="",      )  )  for curve in [i.name for i in curves]:      if curve == "ed25519" or curve == "ed448":          continue      s1 = "from ecdsa import signingkey, ecdh, {0}".format(curve)      s2 = "our = signingkey.generate({0})".format(curve)#私钥      s3 = "remote = signingkey.generate({0}).verifying_key".format(curve)#公钥      s4 = "ecdh = ecdh(private_key=our, public_key=remote)"      s5 = "ecdh.generate_sharedsecret_bytes()"#产生共享密钥      ecdh = do([s1, s2, s3, s4], s5)      print(          ecdh_form.format(              name=curve,              sep=":",              unit="s",              form=".5f",              form_inv=".2f",              ecdh=ecdh,              ecdh_inv=1.0 / ecdh,          )      )  

如何在python中实现ECDSA你知道吗

如何在python中实现ECDSA你知道吗

  from ecdsa import signingkey  sk = signingkey.generate() # uses nist192p生成私钥  vk = sk.verifying_key#在私钥的基础上生成公钥  signature = sk.sign(b"message")#用私钥对消息进行签名  assert vk.verify(signature, b"message")#用公钥去验证。assert为一断言函数:不满足条件直接触发异常忙不执行接下来的代码,括号中为condition  

  from ecdsa import signingkey, nist384p#384位nist素域椭圆曲线,其中私钥/公钥都与特定的曲线相关联,更长的曲线更安全,但时间长,密钥和签名也长  sk = signingkey.generate(curve=nist384p)  vk = sk.verifying_key  signature = sk.sign(b"message")  assert vk.verify(signature, b"message")  

  #将签名密钥(私钥)序列化成不同的格式。  from ecdsa import signingkey, nist384p  sk = signingkey.generate(curve=nist384p)  sk_string = sk.to_string()#最短的调用,然后再重新创建私钥。to_string():将括号内的数字转化为字符串,实际返回的类型bytes  sk2 = signingkey.from_string(sk_string, curve=nist384p)#重新创建私钥,第一个参数是我们要处理的字符,如果点编码无效或不在指定曲线上,from_string()将引发malformedpointerror  print(sk_string.hex())  print(sk2.to_string().hex())  

  from ecdsa import signingkey, nist384p  sk = signingkey.generate(curve=nist384p)  sk_pem = sk.to_pem()#sk.to_pem()和sk.to_der()将把签名密钥序列化为openssl使用的相同格式  sk2 = signingkey.from_pem(sk_pem)#signingkey.from_pem()/.from_der()将撤销这种序列化。这些格式包括了曲线名称,所以你不需要向反序列化器传递曲线标识符。如果文件是畸形的,from_der()和from_pem()将引发unexpectedder或malformedpointerror。  # sk and sk2 are the same key  

  from ecdsa import signingkey, verifyingkey, nist384p  sk = signingkey.generate(curve=nist384p)  vk = sk.verifying_key  vk_string = vk.to_string()#公钥可以用同样的方式进行序列化  vk2 = verifyingkey.from_string(vk_string, curve=nist384p)  # vk and vk2 are the same key  

  from ecdsa import signingkey, verifyingkey, nist384p  sk = signingkey.generate(curve=nist384p)  vk = sk.verifying_key  vk_pem = vk.to_pem()  vk2 = verifyingkey.from_pem(vk_pem)  # vk and vk2 are the same key  

  import os  from ecdsa import nist384p, signingkey  from ecdsa.util import randrange_from_seed__trytryagain#产生随机数  def make_key(seed):    secexp = randrange_from_seed__trytryagain(seed, nist384p.order)    return signingkey.from_secret_exponent(secexp, curve=nist384p)  seed = os.urandom(nist384p.baselen) # or other starting point,返回一个适合加密的比特串  sk1a = make_key(seed)  sk1b = make_key(seed)  # note: sk1a and sk1b are the same key  assert sk1a.to_string() == sk1b.to_string()  sk2 = make_key(b"2-"+seed)  # different key  b为比特  assert sk1a.to_string() != sk2.to_string()  from ecdsa import signingkey, nist384p  sk = signingkey.generate(curve=nist384p)  vk = sk.verifying_key  vk.precompute()  signature = sk.sign(b"message")  assert vk.verify(signature, b"message")  

  # openssl ecparam -name prime256v1 -genkey -out sk.pem  # openssl ec -in sk.pem -pubout -out vk.pem  # echo "data for signing" > data  # openssl dgst -sha256 -sign sk.pem -out data.sig data  # openssl dgst -sha256 -verify vk.pem -signature data.sig data  # openssl dgst -sha256 -prverify sk.pem -signature data.sig data  #openssl 使用 pem 文件格式存储证书和密钥。pem 实质上是 base64 编码的二进制内容  import hashlib#  from ecdsa import signingkey, verifyingkey  from ecdsa.util import sigencode_der, sigdecode_der#从ecdsa.util写入和读取签名  with open("vk.pem") as f:#公钥文件     vk = verifyingkey.from_pem(f.read())  with open("data", "rb") as f:#open()为读取模式,with语句直接调用close方法,r为读模式,w/wb为写模式,rb模式打开二进制文件,消息data     data = f.read()  with open("data.sig", "rb") as f:#消息签名可读模式     signature = f.read()  assert vk.verify(signature, data, hashlib.sha256, sigdecode=sigdecode_der)#公钥验证签名,  with open("sk.pem") as f:#私钥文件     sk = signingkey.from_pem(f.read(), hashlib.sha256)  new_signature = sk.sign_deterministic(data, sigencode=sigencode_der)#用私钥签名生成一个新的签名  with open("data.sig2", "wb") as f:#写模式     f.write(new_signature)  


  # openssl dgst -sha256 -verify vk.pem -signature data.sig2 data  #如果需要与openssl 1.0.0或更早的版本兼容,可以使用ecdsa.util中的sigencode_string和sigdecode_string来分别写入和读取签名。  from ecdsa import signingkey, verifyingkey  with open("sk.pem") as f:      sk = signingkey.from_pem(f.read())  with open("sk.pem", "wb") as f:      f.write(sk.to_pem())  with open("vk.pem") as f:      vk = verifyingkey.from_pem(f.read())  with open("vk.pem", "wb") as f:      f.write(vk.to_pem())  

  #ecdsa.util.prng 工具在这里很方便:它需要一个种子并从中产生一个强的伪随机流。  #os.urandom的函数作为entropy=参数来做不同的事情  #ecdsa的签名生成也需要一个随机数,而且每个签名都必须使用不同的随机数(两次使用相同的数字会立即暴露出私人签名密钥)。  # sk.sign()方法需要一个entropy=参数,其行为与signingkey.generate(entropy=)相同。  from ecdsa.util import prng  from ecdsa import signingkey  rng1 = prng(b"seed")  sk1 = signingkey.generate(entropy=rng1)  rng2 = prng(b"seed")  sk2 = signingkey.generate(entropy=rng2)  # sk1 and sk2 are the same key  

  #如果你调用signingkey.sign_deterministic(data)而不是.sign(data),代码将生成一个确定性的签名,而不是随机的。  # 这使用rfc6979中的算法来安全地生成一个唯一的k值,该值来自于私钥和被签名的信息。每次你用相同的密钥签署相同的信息时,你将得到相同的签名(使用相同的k)。  #创建一个nist521p密钥对  from ecdsa import signingkey, nist521p  sk = signingkey.generate(curve=nist521p)  vk = sk.verifying_key  #从一个主种子创建三个独立的签名密钥  from ecdsa import nist192p, signingkey  from ecdsa.util import randrange_from_seed__trytryagain  def make_key_from_seed(seed, curve=nist192p):      secexp = randrange_from_seed__trytryagain(seed, curve.order)      return signingkey.from_secret_exponent(secexp, curve)  sk1 = make_key_from_seed("1:%s" % seed)  sk2 = make_key_from_seed("2:%s" % seed)  sk3 = make_key_from_seed("3:%s" % seed)  #从磁盘上加载一个验证密钥,并使用十六进制编码以未压缩和压缩的格式打印出来(在x9.62和sec1标准中定义)。  from ecdsa import verifyingkey  with open("public.pem") as f:#加载验证密钥      vk = verifyingkey.from_pem(f.read())  print("uncompressed: {0}".format(vk.to_string("uncompressed").hex()))  print("compressed: {0}".format(vk.to_string("compressed").hex()))  #从压缩格式的十六进制字符串中加载验证密钥,以未压缩的格式输出。  from ecdsa import verifyingkey, nist256p  comp_str = '022799c0d0ee09772fdd337d4f28dc155581951d07082fb19a38aa396b67e77759'  vk = verifyingkey.from_string(bytearray.fromhex(comp_str), curve=nist256p)  print(vk.to_string("uncompressed").hex())  #与远程方进行ecdh密钥交换。  from ecdsa import ecdh, nist256p  ecdh = ecdh(curve=nist256p)  ecdh.generate_private_key()  local_public_key = ecdh.get_public_key()  #send `local_public_key` to remote party and receive `remote_public_key` from remote party  with open("remote_public_key.pem") as e:      remote_public_key = e.read()  ecdh.load_received_public_key_pem(remote_public_key)  secret = ecdh.generate_sharedsecret_bytes()  

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注<计算机技术网(www.ctvol.com)!!>的更多内容!

需要了解更多python教程分享如何在python中实现ECDSA你知道吗,都可以关注python教程分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/pythontutorial/964629.html

(0)
上一篇 2021年12月2日
下一篇 2021年12月2日

精彩推荐