人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

如何在python中實現(xiàn)ECDSA你知道嗎

發(fā)布日期:2021-12-11 00:56 | 文章來源:gibhub
import six
import timeit#查找任何特定代碼執(zhí)行的確切時間
from ecdsa.curves import curves
#定義do函數(shù),計算時間
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為數(shù)字測試套件關于NIST詳解

GF§ (素數(shù)域)曲線,密鑰長度為192、224、256、384和521bit

OpenSSL工具(openssl ecparam -list_curves)所知道的這些曲線的 "簡稱 "是:prime192v1、secp224r1prime256v1、secp384r1secp521r1。它包括比特幣使用的256位曲線secp256k1。它還支持160到512位的Brainpool曲線的常規(guī)(非扭曲)變體。這些曲線的 "簡稱 "是:BrainpoolP160r1, brainpoolP192r1, brainpoolP224r1, brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, brainpoolP512r1。少數(shù)來自SEC標準的小曲線也包括在內(主要是為了加快庫的測試),它們是:secp112r1, secp112r2, secp128r1, 和secp160r1。沒有包括其他的曲線,但要增加對更多素數(shù)域的曲線的支持并不難。

#不是很懂 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()函數(shù)
 S6 = "vk.precompute()"#不懂
 S7 = "vk.verify(sig, msg)"#用公鑰驗證簽名
 # 我們碰巧知道.generate()也在計算驗證密鑰,這是最耗時的部分。如果將代碼改為懶惰地計算vk,我們就需要將這個基準改為在S5上循環(huán),而不是在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)、簽署數(shù)據(jù)(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",#小數(shù)點后面為5位
form_inv=".2f",#小數(shù)點后面為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,
  )
 )


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為一斷言函數(shù):不滿足條件直接觸發(fā)異常忙不執(zhí)行接下來的代碼,括號中為condition
from ecdsa import SigningKey, NIST384p#384位NIST素域橢圓曲線,其中私鑰/公鑰都與特定的曲線相關聯(lián),更長的曲線更安全,但時間長,密鑰和簽名也長
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()#最短的調用,然后再重新創(chuàng)建私鑰。to_string():將括號內的數(shù)字轉化為字符串,實際返回的類型bytes
sk2 = SigningKey.from_string(sk_string, curve=NIST384p)#重新創(chuàng)建私鑰,第一個參數(shù)是我們要處理的字符,如果點編碼無效或不在指定曲線上,from_string()將引發(fā)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()將引發(fā)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#產生隨機數(shù)
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的函數(shù)作為entropy=參數(shù)來做不同的事情
#ECDSA的簽名生成也需要一個隨機數(shù),而且每個簽名都必須使用不同的隨機數(shù)(兩次使用相同的數(shù)字會立即暴露出私人簽名密鑰)。
# sk.sign()方法需要一個entropy=參數(shù),其行為與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)。
#創(chuàng)建一個NIST521p密鑰對
from ecdsa import SigningKey, NIST521p
sk = SigningKey.generate(curve=NIST521p)
vk = sk.verifying_key
#從一個主種子創(chuàng)建三個獨立的簽名密鑰
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()

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注本站的更多內容!

版權聲明:本站文章來源標注為YINGSOO的內容版權均為本站所有,歡迎引用、轉載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。

相關文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務

7x24全年不間斷在線

專屬顧問服務

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務熱線

關注
微信

關注官方微信
頂部