Kukhala wopanga malaibulale (GOST cryptographic primitives in pure Python), nthawi zambiri ndimalandira mafunso okhudza momwe ndingagwiritsire ntchito mauthenga otetezeka kwambiri pa bondo. Anthu ambiri amaona kuti cryptography yogwiritsidwa ntchito ndiyosavuta, ndipo kuyimba .encrypt() pa block cipher kumakhala kokwanira kutumiza mosatekeseka panjira yolumikizirana. Ena amakhulupirira kuti kugwiritsa ntchito cryptography ndiye tsogolo la ochepa, ndipo ndizovomerezeka kuti makampani olemera ngati Telegraph ndi akatswiri a masamu a olympiad. chitetezo protocol.
Zonsezi zidandipangitsa kuti ndilembe nkhaniyi kuti ndiwonetse kuti kukhazikitsa ma protocol a cryptographic ndi chitetezo cha IM si ntchito yovuta. Komabe, sikuli koyenera kuti mupange ma protocol anu otsimikizika komanso ofunikira.

Nkhaniyi idzalemba , , mthenga wapompopompo ndi kutsimikizika ndi ma protocol ofunikira (kutengera momwe amagwiritsidwira ntchito ), pogwiritsa ntchito laibulale ya GOST cryptographic algorithms ya PyGOST ndi laibulale ya mauthenga a ASN.1 (zomwe ndanena kale ). Chofunikira: chiyenera kukhala chophweka kotero kuti chikhoza kulembedwa kuyambira usiku umodzi (kapena tsiku la ntchito), apo ayi si pulogalamu yosavuta. Mwina ili ndi zolakwika, zovuta zosafunikira, zoperewera, kuphatikiza iyi ndi pulogalamu yanga yoyamba kugwiritsa ntchito laibulale ya asyncio.
Kupanga kwa IM
Choyamba, tiyenera kumvetsetsa momwe IM yathu idzawonekera. Kuti zikhale zosavuta, lolani kuti ikhale maukonde a anzanu ndi anzawo, osapezeka otenga nawo mbali. Tidzawonetsa panokha kuti ndi adilesi iti: doko loti mulumikizane nalo kuti mulumikizane ndi wolumikizirana.
Ndikumvetsetsa kuti, panthawiyi, kulingalira kuti kulankhulana kwachindunji kulipo pakati pa makompyuta awiri osagwirizana ndizovuta kwambiri pakugwiritsa ntchito kwa IM. Koma otukula akamakhazikitsa ndodo zamtundu uliwonse za NAT, m'pamenenso tikhalabe pa intaneti ya IPv4, ndi mwayi wofooketsa wa kulumikizana pakati pa makompyuta osasintha. Kodi mungapirire mpaka liti kusowa kwa IPv6 kunyumba ndi kuntchito?
Tidzakhala ndi maukonde a bwenzi ndi abwenzi: onse omwe angagwirizane nawo ayenera kudziwitsidwa pasadakhale. Choyamba, izi zimathandizira kwambiri chilichonse: tidadzidziwitsa tokha, tapeza kapena sitinapeze dzina / fungulo, kulumikizidwa kapena kupitiliza kugwira ntchito, podziwa wolowera. Kachiwiri, nthawi zambiri, imakhala yotetezeka komanso imachotsa ziwopsezo zambiri.
Mawonekedwe a IM adzakhala pafupi ndi mayankho apamwamba , zomwe ndimakonda kwambiri za minimalism yawo ndi filosofi ya njira ya Unix. Pulogalamu ya IM imapanga chikwatu chokhala ndi sockets zitatu za Unix pa interlocutor iliyonse:
- mu-mauthenga otumizidwa kwa interlocutor amalembedwamo;
- kunja - mauthenga olandilidwa kuchokera kwa interlocutor amawerengedwa kuchokera pamenepo;
- boma - powerenga kuchokera pamenepo, timapeza ngati interlocutor ikugwirizana, adilesi / doko.
Kuphatikiza apo, socket ya conn imapangidwa, polemba doko lolowera momwe timayambira kulumikizana ndi interlocutor yakutali.
|-- alice
| |-- in
| |-- out
| `-- state
|-- bob
| |-- in
| |-- out
| `-- state
`- conn
Njirayi imakupatsani mwayi wopanga zodziyimira pawokha zoyendera za IM ndi mawonekedwe ogwiritsa ntchito, chifukwa palibe bwenzi, simungathe kusangalatsa aliyense. Kugwiritsa ndi / kapena , mutha kupeza mawonekedwe azenera ambiri okhala ndi mawu owunikira. Ndipo ndi chithandizo mutha kupeza mzere wolowetsa uthenga wogwirizana ndi GNU Readline.
M'malo mwake, mapulojekiti osayamwitsa amagwiritsa ntchito mafayilo a FIFO. Inemwini, sindimamvetsetsa momwe ndingagwirire ntchito ndi mafayilo mopikisana mu asyncio popanda maziko olembedwa ndi manja kuchokera ku ulusi wodzipereka (Ndakhala ndikugwiritsa ntchito chilankhulo pazinthu zotere kwa nthawi yayitali. ). Chifukwa chake, ndidaganiza zopanga ma socket a Unix domain. Tsoka ilo, izi zimapangitsa kuti zikhale zosatheka kuchita echo 2001:470:dead::babe 6666> conn. Ndinathetsa vutoli pogwiritsa ntchito : echo 2001:470:kufa::babe 6666 | socat - UNIX-CONNECT:conn, socat WERENGANI UNIX-CONNECT:alice/in.
Protocol yoyambirira yosatetezeka
TCP imagwiritsidwa ntchito ngati mayendedwe: imatsimikizira kuperekedwa ndi dongosolo lake. UDP sichitsimikizira chilichonse (chomwe chingakhale chothandiza ngati cryptography ikugwiritsidwa ntchito), koma kuthandizira Python satuluka m'bokosi.
Tsoka ilo, mu TCP mulibe lingaliro la uthenga, kokha mtsinje wa ma byte. Choncho, m'pofunika kubwera ndi mtundu wa mauthenga kuti athe kugawana pakati pawo mu ulusi uwu. Titha kuvomereza kugwiritsa ntchito mtundu wa feed wa mzere. Ndibwino kuti tiyambe, koma tikangoyamba kubisa mauthenga athu, munthu uyu akhoza kuwoneka paliponse pamutuwu. Pamanetiweki, ma protocol otchuka ndi omwe amayamba kutumiza utali wa uthenga mu ma byte. Mwachitsanzo, kuchokera m'bokosi Python ili ndi xdrlib, yomwe imakulolani kuti mugwiritse ntchito mawonekedwe ofanana .
Sitidzagwira ntchito moyenera komanso moyenera ndi kuwerenga kwa TCP - tidzachepetsa kachidindo. Timawerenga zambiri kuchokera ku socket mu loop yosatha mpaka titazindikira uthenga wathunthu. JSON yokhala ndi XML itha kugwiritsidwanso ntchito ngati mawonekedwe anjira iyi. Koma cryptography ikawonjezedwa, deta iyenera kusayinidwa ndikutsimikiziridwa - ndipo izi zidzafunika mawonekedwe ofanana a zinthu, omwe JSON/XML sapereka (zotsatira zotaya zingasiyane).
XDR ndiyoyenera ntchitoyi, komabe ndimasankha ASN.1 yokhala ndi DER encoding ndi laibulale, popeza tidzakhala ndi zinthu zapamwamba kwambiri zomwe nthawi zambiri zimakhala zosangalatsa komanso zosavuta kugwira ntchito. Mosiyana ndi schemaless , kapena , ASN.1 idzayang'ana deta yokha motsutsana ndi schema yolimba.
# Msg ::= CHOICE {
# text MsgText,
# handshake [0] EXPLICIT MsgHandshake }
class Msg(Choice):
schema = ((
("text", MsgText()),
("handshake", MsgHandshake(expl=tag_ctxc(0))),
))
# MsgText ::= SEQUENCE {
# text UTF8String (SIZE(1..MaxTextLen))}
class MsgText(Sequence):
schema = ((
("text", UTF8String(bounds=(1, MaxTextLen))),
))
# MsgHandshake ::= SEQUENCE {
# peerName UTF8String (SIZE(1..256)) }
class MsgHandshake(Sequence):
schema = ((
("peerName", UTF8String(bounds=(1, 256))),
))
Uthenga wolandiridwa udzakhala Msg: mwina mawu a MsgText (okhala ndi gawo limodzi lolemba pakadali pano) kapena meseji ya MsgHandshake (yomwe ili ndi dzina la wolankhulayo). Tsopano zikuwoneka zovuta kwambiri, koma izi ndi maziko amtsogolo.
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ ββββdβs A) β βββββββββ ββββββββ>β β β βMsgHandshake(IdB) β β<βββββββββββββββββββ β β MsgText() β βββββ MsgText() β β β
IM popanda cryptography
Monga ndanenera kale, laibulale ya asyncio idzagwiritsidwa ntchito pazinthu zonse za socket. Tilengeze zomwe tikuyembekezera poyambitsa:
parser = argparse.ArgumentParser(description="GOSTIM")
parser.add_argument(
"--our-name",
required=True,
help="Our peer name",
)
parser.add_argument(
"--their-names",
required=True,
help="Their peer names, comma-separated",
)
parser.add_argument(
"--bind",
default="::1",
help="Address to listen on",
)
parser.add_argument(
"--port",
type=int,
default=6666,
help="Port to listen on",
)
args = parser.parse_args()
OUR_NAME = UTF8String(args.our_name)
THEIR_NAMES = set(args.their_names.split(","))
Khazikitsani dzina lanu (--dzina lathu alice). Onse omwe amayembekezeka olowerana nawo adalembedwa mosiyanitsidwa ndi koma (-mayina awo bob, eve). Kwa aliyense wa interlocutors, chikwatu chokhala ndi sockets Unix chimapangidwa, komanso coroutine ya aliyense mkati, kunja, chigawo:
for peer_name in THEIR_NAMES:
makedirs(peer_name, mode=0o700, exist_ok=True)
out_queue = asyncio.Queue()
OUT_QUEUES[peer_name] = out_queue
asyncio.ensure_future(asyncio.start_unix_server(
partial(unixsock_out_processor, out_queue=out_queue),
path.join(peer_name, "out"),
))
in_queue = asyncio.Queue()
IN_QUEUES[peer_name] = in_queue
asyncio.ensure_future(asyncio.start_unix_server(
partial(unixsock_in_processor, in_queue=in_queue),
path.join(peer_name, "in"),
))
asyncio.ensure_future(asyncio.start_unix_server(
partial(unixsock_state_processor, peer_name=peer_name),
path.join(peer_name, "state"),
))
asyncio.ensure_future(asyncio.start_unix_server(unixsock_conn_processor, "conn"))
Mauthenga ochokera kwa wogwiritsa ntchito ku socket amatumizidwa ku mzere wa IN_QUEUES:
async def unixsock_in_processor(reader, writer, in_queue: asyncio.Queue) -> None:
while True:
text = await reader.read(MaxTextLen)
if text == b"":
break
await in_queue.put(text.decode("utf-8"))
Mauthenga ochokera kwa interlocutors amatumizidwa ku mizere OUT_QUEUES, pomwe deta imalembedwa ku out socket:
async def unixsock_out_processor(reader, writer, out_queue: asyncio.Queue) -> None:
while True:
text = await out_queue.get()
writer.write(("[%s] %s" % (datetime.now(), text)).encode("utf-8"))
await writer.drain()
Mukawerenga kuchokera ku state socket, pulogalamuyi imayang'ana adilesi ya olankhula nawo mu dikishonale ya PEER_ALIVE. Ngati palibe kugwirizana kwa interlocutor panobe, ndiye kuti mzere wopanda kanthu umalembedwa.
async def unixsock_state_processor(reader, writer, peer_name: str) -> None:
peer_writer = PEER_ALIVES.get(peer_name)
writer.write(
b"" if peer_writer is None else (" ".join([
str(i) for i in peer_writer.get_extra_info("peername")[:2]
]).encode("utf-8") + b"n")
)
await writer.drain()
writer.close()
Mukalemba adilesi ku socket ya conn, ntchito yolumikizira "initiator" imayambitsidwa:
async def unixsock_conn_processor(reader, writer) -> None:
data = await reader.read(256)
writer.close()
host, port = data.decode("utf-8").split(" ")
await initiator(host=host, port=int(port))
Tiyeni tilingalire woyambitsa. Choyamba mwachiwonekere chimatsegula cholumikizira ku doko / doko lodziwika ndikutumiza uthenga wogwirana chanza ndi dzina lake:
130 async def initiator(host, port):
131 _id = repr((host, port))
132 logging.info("%s: dialing", _id)
133 reader, writer = await asyncio.open_connection(host, port)
134 # Handshake message {{{
135 writer.write(Msg(("handshake", MsgHandshake((
136 ("peerName", OUR_NAME),
137 )))).encode())
138 # }}}
139 await writer.drain()
Kenako, imadikirira kuyankha kuchokera kuphwando lakutali. Amayesa kuzindikira yankho lomwe likubwera pogwiritsa ntchito pulogalamu ya Msg ASN.1. Timaganiza kuti uthenga wonse udzatumizidwa mu gawo limodzi la TCP ndipo tidzaulandira mwa atomiki tikamayimba .read(). Timayang'ana kuti talandira uthenga wakugwirana chanza.
141 # Wait for Handshake message {{{
142 data = await reader.read(256)
143 if data == b"":
144 logging.warning("%s: no answer, disconnecting", _id)
145 writer.close()
146 return
147 try:
148 msg, _ = Msg().decode(data)
149 except ASN1Error:
150 logging.warning("%s: undecodable answer, disconnecting", _id)
151 writer.close()
152 return
153 logging.info("%s: got %s message", _id, msg.choice)
154 if msg.choice != "handshake":
155 logging.warning("%s: unexpected message, disconnecting", _id)
156 writer.close()
157 return
158 # }}}
Timayang'ana kuti dzina lolandilidwa la interlocutor limadziwika kwa ife. Ngati sichoncho, ndiye kuti timaphwanya mgwirizano. Timayang'ana ngati takhazikitsa kale kugwirizana ndi iye (wothandizira adaperekanso lamulo kuti agwirizane ndi ife) ndikutseka. Mzere wa IN_QUEUES umakhala ndi zingwe za Python ndi mawu a uthengawo, koma uli ndi mtengo wapadera wa Palibe womwe umawonetsa msg_sender coroutine kuti asiye kugwira ntchito kuti ayiwale za wolemba wake wokhudzana ndi kulumikizana kwa TCP cholowa.
159 msg_handshake = msg.value
160 peer_name = str(msg_handshake["peerName"])
161 if peer_name not in THEIR_NAMES:
162 logging.warning("unknown peer name: %s", peer_name)
163 writer.close()
164 return
165 logging.info("%s: session established: %s", _id, peer_name)
166 # Run text message sender, initialize transport decoder {{{
167 peer_alive = PEER_ALIVES.pop(peer_name, None)
168 if peer_alive is not None:
169 peer_alive.close()
170 await IN_QUEUES[peer_name].put(None)
171 PEER_ALIVES[peer_name] = writer
172 asyncio.ensure_future(msg_sender(peer_name, writer))
173 # }}}
msg_sender amavomereza mauthenga otuluka (omwe ali pamzere kuchokera mu socket), amawasintha kukhala meseji ya MsgText ndikuwatumiza pa intaneti ya TCP. Ikhoza kusweka nthawi iliyonse - timamvetsetsa bwino izi.
async def msg_sender(peer_name: str, writer) -> None:
in_queue = IN_QUEUES[peer_name]
while True:
text = await in_queue.get()
if text is None:
break
writer.write(Msg(("text", MsgText((
("text", UTF8String(text)),
)))).encode())
try:
await writer.drain()
except ConnectionResetError:
del PEER_ALIVES[peer_name]
return
logging.info("%s: sent %d characters message", peer_name, len(text))
Pamapeto pake, woyambitsayo amalowa m'njira yosawerengeka yowerengera mauthenga kuchokera ku socket. Imawunika ngati mamesejiwa ndi mameseji ndikuwayika pamzere wa OUT_QUEUES, pomwe adzatumizidwa ku socket yakunja kwa wolumikizana nawo. Chifukwa chiyani simungangochita .read() ndikutsitsa uthengawo? Chifukwa ndizotheka kuti mauthenga angapo kuchokera kwa wogwiritsa ntchito adzaphatikizidwa mu buffer ya opareshoni ndikutumizidwa mu gawo limodzi la TCP. Titha kusankha yoyamba, ndiyeno gawo lotsatira likhoza kukhalabe mu buffer. Pakakhala zovuta zilizonse, timatseka kulumikiza kwa TCP ndikuyimitsa msg_sender coroutine (potumiza Palibe pamzere wa OUT_QUEUES).
174 buf = b""
175 # Wait for test messages {{{
176 while True:
177 data = await reader.read(MaxMsgLen)
178 if data == b"":
179 break
180 buf += data
181 if len(buf) > MaxMsgLen:
182 logging.warning("%s: max buffer size exceeded", _id)
183 break
184 try:
185 msg, tail = Msg().decode(buf)
186 except ASN1Error:
187 continue
188 buf = tail
189 if msg.choice != "text":
190 logging.warning("%s: unexpected %s message", _id, msg.choice)
191 break
192 try:
193 await msg_receiver(msg.value, peer_name)
194 except ValueError as err:
195 logging.warning("%s: %s", err)
196 break
197 # }}}
198 logging.info("%s: disconnecting: %s", _id, peer_name)
199 IN_QUEUES[peer_name].put(None)
200 writer.close()
66 async def msg_receiver(msg_text: MsgText, peer_name: str) -> None:
67 text = str(msg_text["text"])
68 logging.info("%s: received %d characters message", peer_name, len(text))
69 await OUT_QUEUES[peer_name].put(text)
Tiyeni tibwerere ku code yayikulu. Pambuyo popanga ma coroutines onse panthawi yomwe pulogalamuyo ikuyamba, timayamba seva ya TCP. Pa kulumikizana kulikonse komwe kukhazikitsidwa, kumapanga njira yoyankha.
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s %(asctime)s: %(funcName)s: %(message)s",
)
loop = asyncio.get_event_loop()
server = loop.run_until_complete(asyncio.start_server(responder, args.bind, args.port))
logging.info("Listening on: %s", server.sockets[0].getsockname())
loop.run_forever()
woyankha ndi wofanana ndi woyambitsa ndikuwonetsa zochita zonse zomwezo, koma kuchuluka kwa mauthenga kumayamba nthawi yomweyo, kuti zikhale zosavuta. Pakalipano, ndondomeko yogwirana chanza imatumiza uthenga umodzi kuchokera kumbali iliyonse, koma m'tsogolomu padzakhala awiri kuchokera kwa woyambitsa kugwirizana, pambuyo pake mauthenga amatha kutumizidwa nthawi yomweyo.
72 async def responder(reader, writer):
73 _id = writer.get_extra_info("peername")
74 logging.info("%s: connected", _id)
75 buf = b""
76 msg_expected = "handshake"
77 peer_name = None
78 while True:
79 # Read until we get Msg message {{{
80 data = await reader.read(MaxMsgLen)
81 if data == b"":
82 logging.info("%s: closed connection", _id)
83 break
84 buf += data
85 if len(buf) > MaxMsgLen:
86 logging.warning("%s: max buffer size exceeded", _id)
87 break
88 try:
89 msg, tail = Msg().decode(buf)
90 except ASN1Error:
91 continue
92 buf = tail
93 # }}}
94 if msg.choice != msg_expected:
95 logging.warning("%s: unexpected %s message", _id, msg.choice)
96 break
97 if msg_expected == "text":
98 try:
99 await msg_receiver(msg.value, peer_name)
100 except ValueError as err:
101 logging.warning("%s: %s", err)
102 break
103 # Process Handshake message {{{
104 elif msg_expected == "handshake":
105 logging.info("%s: got %s message", _id, msg_expected)
106 msg_handshake = msg.value
107 peer_name = str(msg_handshake["peerName"])
108 if peer_name not in THEIR_NAMES:
109 logging.warning("unknown peer name: %s", peer_name)
110 break
111 writer.write(Msg(("handshake", MsgHandshake((
112 ("peerName", OUR_NAME),
113 )))).encode())
114 await writer.drain()
115 logging.info("%s: session established: %s", _id, peer_name)
116 peer_alive = PEER_ALIVES.pop(peer_name, None)
117 if peer_alive is not None:
118 peer_alive.close()
119 await IN_QUEUES[peer_name].put(None)
120 PEER_ALIVES[peer_name] = writer
121 asyncio.ensure_future(msg_sender(peer_name, writer))
122 msg_expected = "text"
123 # }}}
124 logging.info("%s: disconnecting", _id)
125 if msg_expected == "text":
126 IN_QUEUES[peer_name].put(None)
127 writer.close()
Chitetezo cha protocol
Yakwana nthawi yoti titeteze mauthenga athu. Tikutanthauza chiyani ndi chitetezo ndipo tikufuna chiyani:
- chinsinsi cha mauthenga opatsirana;
- zowona ndi kukhulupirika kwa mauthenga opatsirana - zosintha zawo ziyenera kudziwika;
- chitetezo pakuwukiridwanso - mfundo yosowa kapena mauthenga obwerezabwereza iyenera kuzindikirika (ndipo taganiza zothetsa kulumikizana);
- kuzindikiritsa ndi kutsimikizira kwa interlocutors pogwiritsa ntchito makiyi omwe adalowetsedwa kale - tidaganiza kale kuti tikupanga maukonde a bwenzi ndi anzathu. Pokhapokha pambuyo potsimikizika tidzamvetsetsa yemwe tikulankhula naye;
- kupezeka katundu (PFS) - kusokoneza chinsinsi chathu chosaina chomwe chakhala nthawi yayitali sikuyenera kupangitsa kuti tizitha kuwerenga makalata onse am'mbuyomu. Kujambulitsa magalimoto oletsedwa kumakhala kopanda phindu;
- kutsimikizika / kutsimikizika kwa mauthenga (mayendedwe ndi kugwirana chanza) mkati mwa gawo limodzi la TCP. Kuyika mauthenga osainidwa bwino / ovomerezeka kuchokera ku gawo lina (ngakhale ndi wolankhulana yemweyo) sikuyenera kutheka;
- wongoyang'ana chabe sayenera kuwona zozindikiritsa ogwiritsa ntchito, makiyi a anthu omwe akhalapo kwanthawi yayitali, kapena ma heshi kuchokera kwa iwo. Kusadziwika kwina kochokera kwa wongoonerera chabe.
Chodabwitsa n'chakuti, pafupifupi aliyense amafuna kukhala ndi zochepa izi mu ndondomeko ya kugwirana chanza, ndipo zochepa kwambiri zomwe zili pamwambazi zimakwaniritsa ndondomeko za "homegrown". Tsopano sitipanga china chatsopano. Ine ndithudi amalangiza ntchito pomanga ma protocol, koma tiyeni tisankhe chosavuta.
Ma protocol awiri omwe amadziwika kwambiri ndi awa:
- - ndondomeko yovuta kwambiri yomwe ili ndi mbiri yakale ya nsikidzi, kugwedezeka, zofooka, malingaliro oipa, zovuta ndi zofooka (komabe, izi sizikugwirizana ndi TLS 1.3). Koma sitikuziganizira chifukwa ndizovuta kwambiri.
- Ρ - alibe mavuto aakulu a cryptographic, ngakhale kuti nawonso si ophweka. Mukawerenga za IKEv1 ndi IKEv2, ndiye kuti gwero lawo ndi , ISO/IEC IS 9798-3 ndi SIGMA (SIGn-ndi-MAc) protocol - yosavuta kugwiritsa ntchito madzulo amodzi.
Ubwino wa SIGMA ndi chiyani, monga ulalo waposachedwa kwambiri pakupanga ma protocol a STS/ISO? Imakwaniritsa zofunikira zathu zonse (kuphatikiza zozindikiritsa za "kubisala") ndipo ilibe zovuta zodziwika bwino zachinsinsi. Ndi minimalistic - kuchotsa chinthu chimodzi mu uthenga wa protocol kumabweretsa kusatetezeka kwake.
Tiyeni tichoke ku protocol yosavuta yokulira kunyumba kupita ku SIGMA. Ntchito yofunika kwambiri yomwe timakondwera nayo ndi : Ntchito yomwe imatulutsa onse omwe atenga nawo mbali pamtengo wofanana, womwe ungagwiritsidwe ntchito ngati kiyi yofananira. Popanda kulowa mwatsatanetsatane: aliyense wa maphwando amapanga ephemeral (yogwiritsidwa ntchito mkati mwa gawo limodzi) makiyi awiri (makiyi apagulu ndi achinsinsi), kusinthana makiyi a anthu onse, kuyitanira ntchito ya mgwirizano, kuti alowetse makiyi awo achinsinsi komanso pagulu. kiyi ya interlocutor.
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ βββ Pu,Abβ β βββββββββββ βββββββββββ βββββββββββββββ>β βPrvA, ββPrvA,Pu β ββββββββ ββββββββββββ β IdB, PubB β ββββββββββββββββββββββββββββββββββββββββ β<ββββββββ βββββββ βPrvB, PubB = DHgen ()β β β ββββββββββββββββββββββββββββββββ ββββ βββββ ββββ§βββββββββββββ β βKey = DH(PrvA, PubB)β <βββββββββββββββββββββ βββββββ βββββ β β β β
Aliyense akhoza kudumphira pakati ndikusintha makiyi a anthu onse ndi awo - palibe kutsimikizika kwa interlocutors mu protocol iyi. Tiyeni tiwonjezere siginecha yokhala ndi makiyi omwe akhalapo nthawi yayitali.
βββββββ ββ- SignPrvA, (PubA)) β ββ ββββββββββββ ββββββββββ ββββββββββββ bA = katundu()β β β βPrvA, PubA = DHgen() β β β ββββββββ βββββββ ββββββββββββββββββββββ , chizindikiro(SignPrvB, (PubB)) β βββββββββββββββ βββββββ βββββββββ βββββββ ββββββββββ βββββββββββββ βββ βSignPrvB, SignPubB = katundu( )β β β βPrvB, Pub β β β β β βββββββββ ββββββββββββββ βββ βββββ β ββββββ β β βverify( SignPubB, ...)β β <ββββ βKey = DH(Pr vA, PubB) β β β βββββββββββββββββββββββββββββββββββββββββββββββ ββ β β β
Kusaina koteroko sikungagwire ntchito, chifukwa sikumangirizidwa ku gawo linalake. Mauthenga otere nawonso ndi βoyeneraβ pamisonkhano ndi anthu ena. Nkhani yonse iyenera kulembetsa. Izi zimatikakamiza kuwonjezera uthenga wina kuchokera kwa A.
Kuphatikiza apo, ndikofunikira kuti muwonjezere chizindikiritso chanu pansi pa siginecha, popeza apo ayi titha kulowa m'malo mwa IdXXX ndikusayinanso uthengawo ndi kiyi ya wolumikizana wina wodziwika. Kupewa , m'pofunika kuti zinthu zomwe zili pansi pa siginecha zikhale m'malo omveka bwino malinga ndi tanthauzo lake: ngati zizindikiro A (PubA, PubB), ndiye B ayenera kusaina (PubB, PubA). Izi zikukambanso za kufunikira kosankha kapangidwe kake ndi mawonekedwe a deta yosawerengeka. Mwachitsanzo, ma encoding a ASN.1 DER asinthidwa: SET OF(PubA, PubB) idzakhala yofanana ndi SET OF(PubB, PubA).
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ βββ Pu,Abβ β βββββββββββ ββββββββββββββββ βββββββββββββββββββ βββββββββ ββββββββββββ>β βSignPrvA, SignPubA = katundu()β β β βPrvA, PubA = DHgen() β β β β βββββββ ββββββββββββββββ βIdB, PubB, sign(SignPrvB, (IdB, PubA, PubB)) βββββ ββββββββββββ β<βββββββββββββββββββββββ βββββββββ ββββββββββ βSignPrvB, SignPubB = katundu()β β β βPrvB, PubB = DHgen() β β β β βββ ββββ ββββββββ βββββββββββ β chizindikiro(SignPrvA, (IdA, PubB, PubA)) βββββ ββ ββββββββββββββββββββββββββββββββββββββββ βββ>β βverify(SignPubB, ...) β β β βkey = dh (prva, PUBB) β β β β
Komabe, "sitinatsimikizire" kuti tapanga makiyi omwewo a gawoli. M'malo mwake, titha kuchita popanda sitepe iyi - kulumikizana koyamba koyendera kudzakhala kosavomerezeka, koma tikufuna kuti kugwirana chanza kukatsirizika, tidzakhala otsimikiza kuti zonse zikugwirizana. Pakadali pano tili ndi protocol ya ISO/IEC IS 9798-3.
Titha kusaina kiyi yopangidwa yokha. Izi ndizowopsa, chifukwa ndizotheka kuti pakhoza kukhala kutayikira mu siginecha ya algorithm yomwe imagwiritsidwa ntchito (ngakhale bits-per-signature, koma ikutuluka). Ndizotheka kusaina hashi ya kiyi yotengera, koma kutayikira ngakhale hashi ya kiyi yochokera kungakhale kofunikira pakuwukira mwamphamvu pa ntchito yotengera. SIGMA imagwiritsa ntchito ntchito ya MAC yomwe imatsimikizira ID ya wotumiza.
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ βββ Pu,Abβ β βββββββββββ ββββββββββββββββ βββββββββββββββββββ βββββββββ ββββββββββββββββ- β βββββββ βββββββββββββββββββββ βIdB, PubB, sign(SignPrvB, (PubA, PubIB)ββ), MAC ββββ βββ β<ββββββββββββββββ ββββββββββ βββββ βββββββββ ββ βSignPrvB, SignPubB = katundu()β β β βPrvB, PubB = DHgen() β β β βββββ βββββββββββββββββββββ βββββββββ βββ β β βββββββββββββ ββββββββββββ β sign),(PubAc),(Pub) β βKiyi = DH( PrvA, PubB) β βββββββββββββββββββββ ββ ββββββββββββ βββββββββ ββββ>β βverify(Key, IdB) β β β βverify(SignPubB, ...)β β β βββββββββββββββββββββββββββββββ βββββ ββ β β
Monga kukhathamiritsa, ena angafune kugwiritsanso ntchito makiyi awo a ephemeral (zomwe ziri, zatsoka kwa PFS). Mwachitsanzo, tinapanga awiri ofunikira, kuyesera kugwirizanitsa, koma TCP sinalipo kapena inasokonezedwa kwinakwake pakati pa protocol. Ndizochititsa manyazi kuwononga chuma cha entropy ndi purosesa pagulu latsopano. Chifukwa chake, tikuwonetsa zomwe zimatchedwa cookie - mtengo wabodza womwe ungatetezedwe kuzinthu zomwe zingachitike mwachisawawa mukamagwiritsanso ntchito makiyi a anthu a ephemeral. Chifukwa chomangirira pakati pa cookie ndi kiyi yapagulu ya ephemeral, kiyi yapagulu ya gulu linalo imatha kuchotsedwa pa siginecha ngati yosafunikira.
_ A β βββββββββ βββββββββββββββββββ βββββββββββββββ βββββββββ ββββββββββββββββββββββββββββββββββββββββ β>β βSignPrvA, SignPubA = katundu( )β β β βPrvA, PubA = DHgen() β β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ βββ βIdB, PubB, CookieB , chizindikiro(SignPrvB, (CookieA, CookieB, PubB)), MAC(IdB) β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β< ββββββββββββββββββββββββββββββββββββββββ βββββββββ ββββββββββββββββ- β βββββββ ββββββββββββββββββββββ β β ββββββββββββββββ ββββββββ β chizindikiro( SignPrvA, (CookieB, CookieA, PubA)), MAC(IdA) β βKey = DH(PrvA, PubB) β βββββββββββββββββββ β ββ ββββββββββββββββββββββββββββββββββββββββ βββββββ>β β verify(Key, IdB) β β β βverify(SignPubB, ...)β β β βββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
Pomaliza, tikufuna kupeza zinsinsi za omwe timacheza nawo kuchokera kwa munthu wongoonerera chabe. Kuti izi zitheke, SIGMA ikufuna kusinthanitsa makiyi a ephemeral kaye ndikupanga kiyi wamba yomwe ingasungirepo mauthenga otsimikizira ndi kuzindikira. SIGMA ikufotokoza njira ziwiri:
- SIGMA-I - imateteza woyambitsa ku kuukira kogwira ntchito, woyankha kuchokera kuzinthu zopanda pake: woyambitsa amatsimikizira woyankhayo ndipo ngati chinachake sichikugwirizana, ndiye kuti sichimapereka chizindikiritso chake. Wotsutsa amapereka chizindikiritso chake ngati protocol yogwira iyambika ndi iye. Woyang'anitsitsa saphunzira kanthu;
SIGMA-R - imateteza woyankha kuti asawukidwe, woyambitsa kuchokera kuzinthu zopanda pake. Chilichonse chiri chosiyana ndendende, koma mu protocol iyi mauthenga anayi ogwirana chanza amafalitsidwa kale.Timasankha SIGMA-I chifukwa ndizofanana ndi zomwe timayembekezera kuchokera kuzinthu zodziwika bwino za kasitomala: kasitomala amadziwika ndi seva yotsimikizika, ndipo aliyense amadziwa kale seva. Kuphatikizanso ndikosavuta kukhazikitsa chifukwa cha mauthenga ocheperako akugwirana chanza. Zomwe timawonjezera pa protocol ndikubisa gawo la uthenga ndikusamutsa chizindikiritso A kupita ku gawo lobisika la uthenga womaliza:
PubA, cookieA βββββββββ βββββ ββββββββββ ββββββββββββββββββββββββ ββββββββββ βββββ ββββ- ββββββββ βββββββββ βββββ β PubB, CookieB, Enc((IdB, sign(SignPrvB, (CookieA, CookieB, PubB)), MAC(Idββββ) ββββββββββββββ ββββββββ β<ββββββ βββββββββ βββββ ββββββββββ βSignP rvB, SignPubB = katundu()β β β β PrvB, PubB = DHgen β β ββββββββ βββββββββββββββββ β β βββββββββ βββββββββββββββββββββββββ βββ β Enc((IdA, sign( SignPrvA, (CookieB, CookieA, PubA)), MAC(IdA))) β βKey = DH(PrvA, PubB) β ββββββββββββββββββ β βββββββββββββββββ ββββββββββ βββββββββββββ ββββββββββ ββββββ>β βverify(Key, IdB) β β β βverify( SignPubB, ...)β β β ββββββββββββββββββββββ βββββ βββ β β
- GOST R imagwiritsidwa ntchito posayina algorithm yokhala ndi makiyi a 256-bit.
- Kuti apange kiyi yapagulu, 34.10/2012/XNUMX VKO imagwiritsidwa ntchito.
- CMAC imagwiritsidwa ntchito ngati MAC. Mwaukadaulo, iyi ndi njira yapadera yogwiritsira ntchito block cipher, yofotokozedwa mu GOST R 34.13-2015. Monga ntchito yobisa pamachitidwe awa - (34.12-2015).
- Hashi ya kiyi yake yapagulu imagwiritsidwa ntchito ngati chizindikiritso cha interlocutor. Amagwiritsidwa ntchito ngati hash (34.11/2012/256 XNUMX bits).
Pambuyo pakugwirana chanza, tidzagwirizana pa kiyi yogawana. Titha kugwiritsa ntchito kubisa kwa mauthenga otsimikizika. Gawo ili ndi losavuta komanso lovuta kulakwitsa: timawonjezera kauntala ya uthenga, kubisa uthengawo, kutsimikizira (MAC) kauntala ndi zolemba, kutumiza. Tikalandira uthenga, timayang'ana ngati kauntala ili ndi mtengo woyembekezeka, kutsimikizira mawu achinsinsi ndi kauntala, ndikuyimasulira. Ndi fungulo lanji lomwe ndiyenera kugwiritsa ntchito pobisa mauthenga ogwirana chanza, mauthenga oyendetsa, ndi momwe ndingawatsimikizire? Kugwiritsa ntchito kiyi imodzi pazochitika zonsezi ndi koopsa komanso kopanda nzeru. Ndikofunikira kupanga makiyi pogwiritsa ntchito ntchito zapadera (makiyi otengera ntchito). Apanso, tisamagawane tsitsi ndikupanga china chake: wakhala akudziwika, akufufuzidwa bwino ndipo alibe mavuto odziwika. Tsoka ilo, laibulale yaku Python ilibe ntchitoyi, chifukwa chake timagwiritsa ntchito thumba la pulasitiki. HKDF imagwiritsa ntchito mkati , yomwe imagwiritsanso ntchito hash. Kukhazikitsa kwachitsanzo ku Python patsamba la Wikipedia kumangotengera mizere ingapo. Monga momwe zilili ndi 34.10/2012/256, tidzagwiritsa ntchito Stribog-XNUMX ngati ntchito ya hashi. Zotsatira za ntchito yathu yofunikira zidzatchedwa kiyi ya gawo, pomwe zosowa zofananira zidzapangidwa:
kdf = Hkdf(None, key_session, hash=GOST34112012256) kdf.expand(b"handshake1-mac-identity") kdf.expand(b"handshake1-enc") kdf.expand(b"handshake1-mac") kdf.expand(b"handshake2-mac-identity") kdf.expand(b"handshake2-enc") kdf.expand(b"handshake2-mac") kdf.expand(b"transport-initiator-enc") kdf.expand(b"transport-initiator-mac") kdf.expand(b"transport-responder-enc") kdf.expand(b"transport-responder-mac")Kapangidwe/Njira
Tiyeni tiwone zomwe ASN.1 ali nazo tsopano potumiza deta yonseyi:
class Msg(Choice): schema = (( ("text", MsgText()), ("handshake0", MsgHandshake0(expl=tag_ctxc(0))), ("handshake1", MsgHandshake1(expl=tag_ctxc(1))), ("handshake2", MsgHandshake2(expl=tag_ctxc(2))), )) class MsgText(Sequence): schema = (( ("payload", MsgTextPayload()), ("payloadMac", MAC()), )) class MsgTextPayload(Sequence): schema = (( ("nonce", Integer(bounds=(0, float("+inf")))), ("ciphertext", OctetString(bounds=(1, MaxTextLen))), )) class MsgHandshake0(Sequence): schema = (( ("cookieInitiator", Cookie()), ("pubKeyInitiator", PubKey()), )) class MsgHandshake1(Sequence): schema = (( ("cookieResponder", Cookie()), ("pubKeyResponder", PubKey()), ("ukm", OctetString(bounds=(8, 8))), ("ciphertext", OctetString()), ("ciphertextMac", MAC()), )) class MsgHandshake2(Sequence): schema = (( ("ciphertext", OctetString()), ("ciphertextMac", MAC()), )) class HandshakeTBE(Sequence): schema = (( ("identity", OctetString(bounds=(32, 32))), ("signature", OctetString(bounds=(64, 64))), ("identityMac", MAC()), )) class HandshakeTBS(Sequence): schema = (( ("cookieTheir", Cookie()), ("cookieOur", Cookie()), ("pubKeyOur", PubKey()), )) class Cookie(OctetString): bounds = (16, 16) class PubKey(OctetString): bounds = (64, 64) class MAC(OctetString): bounds = (16, 16)HandshakeTBS ndi yomwe idzasainidwe. HandshakeTBE - zomwe zidzasinthidwe. Ndikuwonetsani gawo la ukm mu MsgHandshake1. 34.10 VKO, pazambiri zamtundu wa makiyi opangidwa, kuphatikiza UKM (user keying material) parameter - entropy yowonjezera.
Kuwonjezera Cryptography ku Code
Tiyeni tingoganizira zosintha zomwe zidapangidwa ku code yoyambirira, popeza chimangocho chidakhalabe chofanana (kwenikweni, kukhazikitsidwa komaliza kudalembedwa koyamba, ndiyeno cryptography yonse idadulidwa).
Popeza kutsimikizika ndi kuzindikiritsa ophatikizana kudzachitidwa pogwiritsa ntchito makiyi apagulu, tsopano akuyenera kusungidwa kwinakwake kwa nthawi yayitali. Kuti zikhale zosavuta, timagwiritsa ntchito JSON monga chonchi:
{ "our": { "prv": "21254cf66c15e0226ef2669ceee46c87b575f37f9000272f408d0c9283355f98", "pub": "938c87da5c55b27b7f332d91b202dbef2540979d6ceaa4c35f1b5bfca6df47df0bdae0d3d82beac83cec3e353939489d9981b7eb7a3c58b71df2212d556312a1" }, "their": { "alice": "d361a59c25d2ca5a05d21f31168609deeec100570ac98f540416778c93b2c7402fd92640731a707ec67b5410a0feae5b78aeec93c4a455a17570a84f2bc21fce", "bob": "aade1207dd85ecd283272e7b69c078d5fae75b6e141f7649ad21962042d643512c28a2dbdc12c7ba40eb704af920919511180c18f4d17e07d7f5acd49787224a" } }athu - makiyi athu awiri, makiyi a hexadecimal achinsinsi komanso agulu. awo - maina a interlocutors ndi makiyi awo pagulu. Tiyeni tisinthe mikangano yamalamulo ndikuwonjezera kukonzanso kwa data ya JSON:
from pygost import gost3410 from pygost.gost34112012256 import GOST34112012256 CURVE = gost3410.GOST3410Curve( *gost3410.CURVE_PARAMS["GostR3410_2001_CryptoPro_A_ParamSet"] ) parser = argparse.ArgumentParser(description="GOSTIM") parser.add_argument( "--keys-gen", action="store_true", help="Generate JSON with our new keypair", ) parser.add_argument( "--keys", default="keys.json", required=False, help="JSON with our and their keys", ) parser.add_argument( "--bind", default="::1", help="Address to listen on", ) parser.add_argument( "--port", type=int, default=6666, help="Port to listen on", ) args = parser.parse_args() if args.keys_gen: prv_raw = urandom(32) pub = gost3410.public_key(CURVE, gost3410.prv_unmarshal(prv_raw)) pub_raw = gost3410.pub_marshal(pub) print(json.dumps({ "our": {"prv": hexenc(prv_raw), "pub": hexenc(pub_raw)}, "their": {}, })) exit(0) # Parse and unmarshal our and their keys {{{ with open(args.keys, "rb") as fd: _keys = json.loads(fd.read().decode("utf-8")) KEY_OUR_SIGN_PRV = gost3410.prv_unmarshal(hexdec(_keys["our"]["prv"])) _pub = hexdec(_keys["our"]["pub"]) KEY_OUR_SIGN_PUB = gost3410.pub_unmarshal(_pub) KEY_OUR_SIGN_PUB_HASH = OctetString(GOST34112012256(_pub).digest()) for peer_name, pub_raw in _keys["their"].items(): _pub = hexdec(pub_raw) KEYS[GOST34112012256(_pub).digest()] = { "name": peer_name, "pub": gost3410.pub_unmarshal(_pub), } # }}}Kiyi yachinsinsi ya 34.10 algorithm ndi nambala yachisawawa. 256-bit kukula kwa 256-bit elliptic curves. PyGOST sagwira ntchito ndi ma byte, koma ndi , kotero kiyi yathu yachinsinsi (urandom(32)) iyenera kusinthidwa kukhala nambala pogwiritsa ntchito gost3410.prv_unmarshal(). Kiyi yapagulu imatsimikiziridwa motsimikiza kuchokera ku kiyi yachinsinsi pogwiritsa ntchito gost3410.public_key(). Kiyi yapagulu 34.10 ndi ziwerengero zazikulu ziwiri zomwe zimafunikiranso kusinthidwa kukhala kalozera kakang'ono kuti musungidwe mosavuta ndikutumiza pogwiritsa ntchito gost3410.pub_marshal().
Mukawerenga fayilo ya JSON, makiyi a anthu onse ayenera kusinthidwanso pogwiritsa ntchito gost3410.pub_unmarshal(). Popeza tidzalandira zizindikiritso za interlocutors mu mawonekedwe a hashi kuchokera kuchinsinsi cha anthu, akhoza kuwerengedwera nthawi yomweyo ndikuyika mu dikishonale kuti afufuze mwamsanga. Stribog-256 hashi ndi gost34112012256.GOST34112012256(), zomwe zimakwaniritsa mawonekedwe a hashib a hashi.
Kodi njira yoyambira yasintha bwanji? Chilichonse chili molingana ndi chiwembu chogwirana chanza: timapanga cookie (128-bit ndi yochuluka), ephemeral key 34.10, yomwe idzagwiritsidwe ntchito pa mgwirizano waukulu wa VKO.
395 async def initiator(host, port): 396 _id = repr((host, port)) 397 logging.info("%s: dialing", _id) 398 reader, writer = await asyncio.open_connection(host, port) 399 # Generate our ephemeral public key and cookie, send Handshake 0 message {{{ 400 cookie_our = Cookie(urandom(16)) 401 prv = gost3410.prv_unmarshal(urandom(32)) 402 pub_our = gost3410.public_key(CURVE, prv) 403 pub_our_raw = PubKey(gost3410.pub_marshal(pub_our)) 404 writer.write(Msg(("handshake0", MsgHandshake0(( 405 ("cookieInitiator", cookie_our), 406 ("pubKeyInitiator", pub_our_raw), 407 )))).encode()) 408 # }}} 409 await writer.drain()- timadikirira kuyankha ndikusankha uthenga wa Msg womwe ukubwera;
- onetsetsani kuti mwagwirana chanza1;
- zindikirani kiyi yapagulu ya ephemeral ya gulu lina ndikuwerengera makiyi a gawolo;
- Timapanga makiyi ofananira ofunikira pokonza gawo la TBE la uthengawo.
423 logging.info("%s: got %s message", _id, msg.choice) 424 if msg.choice != "handshake1": 425 logging.warning("%s: unexpected message, disconnecting", _id) 426 writer.close() 427 return 428 # }}} 429 msg_handshake1 = msg.value 430 # Validate Handshake message {{{ 431 cookie_their = msg_handshake1["cookieResponder"] 432 pub_their_raw = msg_handshake1["pubKeyResponder"] 433 pub_their = gost3410.pub_unmarshal(bytes(pub_their_raw)) 434 ukm_raw = bytes(msg_handshake1["ukm"]) 435 ukm = ukm_unmarshal(ukm_raw) 436 key_session = kek_34102012256(CURVE, prv, pub_their, ukm, mode=2001) 437 kdf = Hkdf(None, key_session, hash=GOST34112012256) 438 key_handshake1_mac_identity = kdf.expand(b"handshake1-mac-identity") 439 key_handshake1_enc = kdf.expand(b"handshake1-enc") 440 key_handshake1_mac = kdf.expand(b"handshake1-mac")UKM ndi nambala ya 64-bit (urandom(8)), yomwe imafunanso kuchotsedwa kwa mawonekedwe ake pogwiritsa ntchito gost3410_vko.ukm_unmarshal(). VKO ntchito ya 34.10/2012/256 3410-bit ndi gost34102012256_vko.kek_XNUMX () (KEK - encryption key).
Kiyi yagawo yopangidwa kale ndi 256-bit pseudo-random byte sequence. Chifukwa chake, itha kugwiritsidwa ntchito nthawi yomweyo muzochita za HKDF. Popeza GOST34112012256 imakwaniritsa mawonekedwe a hahlib, imatha kugwiritsidwa ntchito nthawi yomweyo m'gulu la Hkdf. Sititchula mchere (mkangano woyamba wa Hkdf), popeza kiyi yopangidwa, chifukwa cha ephemerality ya awiriawiri ofunikira, idzakhala yosiyana pa gawo lililonse ndipo ili kale ndi entropy yokwanira. kdf.expand() mwachisawawa imapanga kale makiyi a 256-bit omwe amafunikira Grasshopper pambuyo pake.
Kenako, magawo a TBE ndi TBS a uthenga wobwera amawunikidwa:
- MAC pa ciphertext yomwe ikubwera imawerengedwa ndikufufuzidwa;
- ciphertext ndi decrypted;
- Mapangidwe a TBE asinthidwa;
- chizindikiritso cha interlocutor amatengedwa mmenemo ndipo amafufuzidwa ngati iye amadziwika kwa ife konse;
- MAC pamwamba pa chizindikiritsochi imawerengedwa ndikufufuzidwa;
- siginecha yamtundu wa TBS imatsimikiziridwa, yomwe imaphatikizapo cookie ya mbali zonse ziwiri ndi kiyi yapagulu ya chipani china. Siginecha imatsimikiziridwa ndi kiyi yosayina yanthawi yayitali ya interlocutor.
441 try: 442 peer_name = validate_tbe( 443 msg_handshake1, 444 key_handshake1_mac_identity, 445 key_handshake1_enc, 446 key_handshake1_mac, 447 cookie_our, 448 cookie_their, 449 pub_their_raw, 450 ) 451 except ValueError as err: 452 logging.warning("%s: %s, disconnecting", _id, err) 453 writer.close() 454 return 455 # }}} 128 def validate_tbe( 129 msg_handshake: Union[MsgHandshake1, MsgHandshake2], 130 key_mac_identity: bytes, 131 key_enc: bytes, 132 key_mac: bytes, 133 cookie_their: Cookie, 134 cookie_our: Cookie, 135 pub_key_our: PubKey, 136 ) -> str: 137 ciphertext = bytes(msg_handshake["ciphertext"]) 138 mac_tag = mac(GOST3412Kuznechik(key_mac).encrypt, KUZNECHIK_BLOCKSIZE, ciphertext) 139 if not compare_digest(mac_tag, bytes(msg_handshake["ciphertextMac"])): 140 raise ValueError("invalid MAC") 141 plaintext = ctr( 142 GOST3412Kuznechik(key_enc).encrypt, 143 KUZNECHIK_BLOCKSIZE, 144 ciphertext, 145 8 * b"x00", 146 ) 147 try: 148 tbe, _ = HandshakeTBE().decode(plaintext) 149 except ASN1Error: 150 raise ValueError("can not decode TBE") 151 key_sign_pub_hash = bytes(tbe["identity"]) 152 peer = KEYS.get(key_sign_pub_hash) 153 if peer is None: 154 raise ValueError("unknown identity") 155 mac_tag = mac( 156 GOST3412Kuznechik(key_mac_identity).encrypt, 157 KUZNECHIK_BLOCKSIZE, 158 key_sign_pub_hash, 159 ) 160 if not compare_digest(mac_tag, bytes(tbe["identityMac"])): 161 raise ValueError("invalid identity MAC") 162 tbs = HandshakeTBS(( 163 ("cookieTheir", cookie_their), 164 ("cookieOur", cookie_our), 165 ("pubKeyOur", pub_key_our), 166 )) 167 if not gost3410.verify( 168 CURVE, 169 peer["pub"], 170 GOST34112012256(tbs.encode()).digest(), 171 bytes(tbe["signature"]), 172 ): 173 raise ValueError("invalid signature") 174 return peer["name"]Monga ndalemba pamwambapa, 34.13/2015/XNUMX ikufotokoza zosiyanasiyana kuyambira 34.12/2015/3413. Pakati pawo pali njira yopangira zoyika motsanzira ndi kuwerengera kwa MAC. Mu PyGOST izi ndi gost34.12.mac (). Njirayi imafuna kupititsa ntchito yolembera (kulandira ndi kubweza chipika chimodzi cha deta), kukula kwa chipika cha encryption ndipo, kwenikweni, deta yokha. Chifukwa chiyani simungathe kusindikiza kukula kwa block block? 2015/128/64 sikufotokoza za XNUMX-bit Grasshopper cipher, komanso XNUMX-bit - GOST 28147-89 yosinthidwa pang'ono, yomwe idapangidwanso ku KGB ndipo ikadali ndi imodzi mwazinthu zotetezeka kwambiri.
Kuznechik imayambitsidwa poyitana gost.3412.GOST3412Kuznechik(kiyi) ndikubwezeretsa chinthu ndi .encrypt()/.decrypt() njira zoyenera kudutsa ku 34.13 ntchito. MAC imawerengedwa motere: gost3413.mac(GOST3412Kuznechik(key).encrypt, KUZNECHIK_BLOCKSIZE, ciphertext). Kuti mufananize ma MAC owerengeredwa ndi olandilidwa, simungagwiritse ntchito kufananitsa kwanthawi zonse (==) kwa zingwe za byte, popeza ntchitoyi imataya nthawi yofananiza, yomwe, nthawi zambiri, imatha kubweretsa zovuta zakupha ngati. kuukira kwa TLS. Python ili ndi ntchito yapadera, hmac.compare_digest, pa izi.
Ntchito ya block cipher imatha kubisa deta imodzi yokha. Kwa nambala yokulirapo, ndipo ngakhale osachulukitsa kutalika kwake, ndikofunikira kugwiritsa ntchito njira yobisa. 34.13-2015 ikufotokoza zotsatirazi: ECB, CTR, OFB, CBC, CFB. Iliyonse ili ndi madera ake ovomerezeka ogwiritsira ntchito ndi mawonekedwe. Tsoka ilo, tilibe okhazikika (monga CCM, OCB, GCM ndi zina zotero) - tikukakamizika kuwonjezera MAC tokha. Ndikusankha (CTR): sichifunikira padding kukula kwa chipika, ikhoza kufananizidwa, imangogwiritsa ntchito encryption, ingagwiritsidwe ntchito mosamala kubisa mauthenga ambiri (mosiyana ndi CBC, yomwe imagunda mwachangu).
Monga .mac(), .ctr() imalowetsanso chimodzimodzi: ciphertext = gost3413.ctr(GOST3412Kuznechik(key).encrypt, KUZNECHIK_BLOCKSIZE, plaintext, iv). Ndikofunikira kutchula vekitala yoyambira yomwe ili ndendende theka la kutalika kwa chipika chobisa. Ngati kiyi yathu yobisa ikugwiritsidwa ntchito kubisa uthenga umodzi wokha (ngakhale kuchokera ku midadada ingapo), ndiye kuti ndibwino kukhazikitsa zero zoyambira. Kuti tisunge mauthenga akugwirana chanza, timagwiritsa ntchito kiyi yosiyana nthawi iliyonse.
Kutsimikizira siginecha gost3410.verify() n'kochepa: timadutsa elliptic curve mkati momwe tikugwira ntchito (timangolemba mu protocol yathu ya GOSTIM), kiyi yapagulu ya wosayina (musaiwale kuti izi ziyenera kukhala ziwiri ziwiri. ziwerengero zazikulu, osati chingwe chocheperako), 34.11/2012/XNUMX hashi ndi siginecha yokha.
Chotsatira, muzoyambitsa timakonzekera ndikutumiza uthenga wogwirana chanza kwa kugwirana chanza2, kuchita zomwezo monga tidachita pakutsimikizira, molingana: kusaina pa makiyi athu m'malo moyang'ana, ndi zina ...
456 # Prepare and send Handshake 2 message {{{ 457 tbs = HandshakeTBS(( 458 ("cookieTheir", cookie_their), 459 ("cookieOur", cookie_our), 460 ("pubKeyOur", pub_our_raw), 461 )) 462 signature = gost3410.sign( 463 CURVE, 464 KEY_OUR_SIGN_PRV, 465 GOST34112012256(tbs.encode()).digest(), 466 ) 467 key_handshake2_mac_identity = kdf.expand(b"handshake2-mac-identity") 468 mac_tag = mac( 469 GOST3412Kuznechik(key_handshake2_mac_identity).encrypt, 470 KUZNECHIK_BLOCKSIZE, 471 bytes(KEY_OUR_SIGN_PUB_HASH), 472 ) 473 tbe = HandshakeTBE(( 474 ("identity", KEY_OUR_SIGN_PUB_HASH), 475 ("signature", OctetString(signature)), 476 ("identityMac", MAC(mac_tag)), 477 )) 478 tbe_raw = tbe.encode() 479 key_handshake2_enc = kdf.expand(b"handshake2-enc") 480 key_handshake2_mac = kdf.expand(b"handshake2-mac") 481 ciphertext = ctr( 482 GOST3412Kuznechik(key_handshake2_enc).encrypt, 483 KUZNECHIK_BLOCKSIZE, 484 tbe_raw, 485 8 * b"x00", 486 ) 487 mac_tag = mac( 488 GOST3412Kuznechik(key_handshake2_mac).encrypt, 489 KUZNECHIK_BLOCKSIZE, 490 ciphertext, 491 ) 492 writer.write(Msg(("handshake2", MsgHandshake2(( 493 ("ciphertext", OctetString(ciphertext)), 494 ("ciphertextMac", MAC(mac_tag)), 495 )))).encode()) 496 # }}} 497 await writer.drain() 498 logging.info("%s: session established: %s", _id, peer_name)Gawoli likakhazikitsidwa, makiyi oyendera amapangidwa (kiyi yosiyana ya kubisa, kutsimikizika, pagulu lililonse), ndipo Grasshopper imayambitsidwa kuti isinthe ndikuwunika MAC:
499 # Run text message sender, initialize transport decoder {{{ 500 key_initiator_enc = kdf.expand(b"transport-initiator-enc") 501 key_initiator_mac = kdf.expand(b"transport-initiator-mac") 502 key_responder_enc = kdf.expand(b"transport-responder-enc") 503 key_responder_mac = kdf.expand(b"transport-responder-mac") ... 509 asyncio.ensure_future(msg_sender( 510 peer_name, 511 key_initiator_enc, 512 key_initiator_mac, 513 writer, 514 )) 515 encrypter = GOST3412Kuznechik(key_responder_enc).encrypt 516 macer = GOST3412Kuznechik(key_responder_mac).encrypt 517 # }}} 519 nonce_expected = 0 520 # Wait for test messages {{{ 521 while True: 522 data = await reader.read(MaxMsgLen) ... 530 msg, tail = Msg().decode(buf) ... 537 try: 538 await msg_receiver( 539 msg.value, 540 nonce_expected, 541 macer, 542 encrypter, 543 peer_name, 544 ) 545 except ValueError as err: 546 logging.warning("%s: %s", err) 547 break 548 nonce_expected += 1 549 # }}}Msg_sender coroutine tsopano imasunga mauthenga asanawatumize pa intaneti ya TCP. Uthenga uliwonse umakhala ndi mawu ochulukirapo ochulukirapo, omwenso ndi ma vector oyambitsira akabisidwa mumayendedwe. Uthenga uliwonse ndi chipika cha uthenga chimatsimikiziridwa kukhala ndi mtengo wotsutsa wosiyana.
async def msg_sender(peer_name: str, key_enc: bytes, key_mac: bytes, writer) -> None: nonce = 0 encrypter = GOST3412Kuznechik(key_enc).encrypt macer = GOST3412Kuznechik(key_mac).encrypt in_queue = IN_QUEUES[peer_name] while True: text = await in_queue.get() if text is None: break ciphertext = ctr( encrypter, KUZNECHIK_BLOCKSIZE, text.encode("utf-8"), long2bytes(nonce, 8), ) payload = MsgTextPayload(( ("nonce", Integer(nonce)), ("ciphertext", OctetString(ciphertext)), )) mac_tag = mac(macer, KUZNECHIK_BLOCKSIZE, payload.encode()) writer.write(Msg(("text", MsgText(( ("payload", payload), ("payloadMac", MAC(mac_tag)), )))).encode()) nonce += 1Mauthenga obwera amakonzedwa ndi msg_receiver coroutine, yomwe imatsimikizira ndi kubisa:
async def msg_receiver( msg_text: MsgText, nonce_expected: int, macer, encrypter, peer_name: str, ) -> None: payload = msg_text["payload"] if int(payload["nonce"]) != nonce_expected: raise ValueError("unexpected nonce value") mac_tag = mac(macer, KUZNECHIK_BLOCKSIZE, payload.encode()) if not compare_digest(mac_tag, bytes(msg_text["payloadMac"])): raise ValueError("invalid MAC") plaintext = ctr( encrypter, KUZNECHIK_BLOCKSIZE, bytes(payload["ciphertext"]), long2bytes(nonce_expected, 8), ) text = plaintext.decode("utf-8") await OUT_QUEUES[peer_name].put(text)Pomaliza
GOSTIM idapangidwa kuti igwiritsidwe ntchito pazolinga zamaphunziro zokha (popeza sichikuphimbidwa ndi mayeso, osachepera)! Kachidindo kochokera pulogalamu akhoza dawunilodi (Π‘ΡΡΠΈΠ±ΠΎΠ³-256 Ρ ΡΡ: 995bbd368c04e50a481d138c5fa2e43ec7c89bc77743ba8dbabee1fde45de120). ΠΠ°ΠΊ ΠΈ Π²ΡΠ΅ ΠΌΠΎΠΈ ΠΏΡΠΎΠ΅ΠΊΡΡ, ΡΠΈΠΏΠ° , , , , GOSTIM ndi kwathunthu , kugawidwa pansi pa malamulo .
, , membala , Wopanga Python/Go, katswiri wamkulu .
Source: www.habr.com
