ΠΠ°ΡΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° (ΠΠΠ‘Π’ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΡΠΊΠΈ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΈ Π½Π° ΡΠΈΡΡ Python), ΡΠ΅ΡΡΠΎ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌ Π²ΡΠΏΡΠΎΡΠΈ ΠΊΠ°ΠΊ Π½Π° ΠΊΠΎΠ»ΡΠ½ΠΎ Π΄Π° ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΌ ΠΏΡΠΎΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ΅Π½ ΠΎΠ±ΠΌΠ΅Π½ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ. ΠΠ½ΠΎΠ³ΠΎ Ρ ΠΎΡΠ° ΡΡΠΈΡΠ°Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ½Π°ΡΠ° ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ Π·Π° Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ ΠΏΡΠΎΡΡΠ° ΡΠ°Π±ΠΎΡΠ°, ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ΡΠΎ Π½Π° .encrypt() Π½Π° Π±Π»ΠΎΡΠ΅Π½ ΡΠΈΡΡΡ ΡΠ΅ Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π·Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ ΠΏΠΎ ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΠΎΠ½Π΅Π½ ΠΊΠ°Π½Π°Π». ΠΡΡΠ³ΠΈ ΠΏΡΠΊ ΡΠΌΡΡΠ°Ρ, ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ½Π°ΡΠ° ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ Π΅ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Π° ΡΠ°ΠΌΠΎ Π·Π° ΠΌΠ°Π»ΡΠΈΠ½Π° ΠΈ Π΅ ΠΏΡΠΈΠ΅ΠΌΠ»ΠΈΠ²ΠΎ, ΡΠ΅ Π±ΠΎΠ³Π°ΡΠΈΡΠ΅ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ ΠΊΠ°ΡΠΎ Telegram Ρ ΠΌΠ°ΡΠ΅ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ»ΠΈΠΌΠΏΠΈΠ°Π΄ΠΈΡΡΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ΅Π½ ΠΏΡΠΎΡΠΎΠΊΠΎΠ».
ΠΡΠΈΡΠΊΠΎ ΡΠΎΠ²Π° ΠΌΠ΅ ΠΏΠΎΠ΄ΡΠΈΠΊΠ½Π° Π΄Π° Π½Π°ΠΏΠΈΡΠ° ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ, Π·Π° Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ°, ΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΡΠΊΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ ΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ΅Π½ IM Π½Π΅ Π΅ ΡΠΎΠ»ΠΊΠΎΠ²Π° ΡΠ»ΠΎΠΆΠ½Π° Π·Π°Π΄Π°ΡΠ°. ΠΠ±Π°ΡΠ΅, Π½Π΅ Π΅ ΡΠ°Π·ΡΠΌΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ΅ΡΡΠ²Π°Ρ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ Π·Π° ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ²Π°Π½Π΅ ΠΈ ΡΠΏΠΎΡΠ°Π·ΡΠΌΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΠΎΠ²Π΅.

Π ΡΡΠ°ΡΠΈΡΡΠ° ΡΠ΅ Π±ΡΠ΄Π΅ ΠΎΠΏΠΈΡΠ°Π½ , , ΠΈΠ½ΡΡΠ°Π½ΡΠ΅Π½ ΠΌΠ΅ΡΡΠ΅Π½Π΄ΠΆΡΡ Ρ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Π·Π° ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ²Π°Π½Π΅ ΠΈ ΡΠΏΠΎΡΠ°Π·ΡΠΌΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΠΎΠ²Π΅ (Π½Π° Π±Π°Π·Π°ΡΠ° Π½Π° ΠΊΠΎΠΉΡΠΎ Π΅ ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ ), ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΠΈΠ·ΡΡΠ»ΠΎ ΠΠΠ‘Π’ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΡΠΊΠΈ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΈ ΠΎΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° PyGOST ΠΈ ASN.1 ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° (Π·Π° ΠΊΠΎΡΡΠΎ Π²Π΅ΡΠ΅ ). ΠΠ΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΡΠ»ΠΎΠ²ΠΈΠ΅: ΡΠΎΠΉ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΡΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΡΠΎΡΡ, ΡΠ΅ Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π½Π°ΠΏΠΈΡΠ΅ ΠΎΡ Π½ΡΠ»Π° Π·Π° Π΅Π΄ΠΈΠ½ Π²Π΅ΡΠ΅Ρ (ΠΈΠ»ΠΈ ΡΠ°Π±ΠΎΡΠ΅Π½ Π΄Π΅Π½), ΠΈΠ½Π°ΡΠ΅ ΡΠΎΠ²Π° Π²Π΅ΡΠ΅ Π½Π΅ Π΅ ΠΏΡΠΎΡΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°. Π Π½Π΅Ρ ΡΡΡ ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ ΠΈΠΌΠ° Π³ΡΠ΅ΡΠΊΠΈ, ΠΈΠ·Π»ΠΈΡΠ½Π° ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ, Π½Π΅Π΄ΠΎΡΠ°Π·ΡΠΌΠ΅Π½ΠΈΡ, ΠΏΠ»ΡΡ ΡΠΎΠ²Π° Π΅ ΠΌΠΎΡΡΠ° ΠΏΡΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Ρ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° asyncio.
ΠΠΈΠ·Π°ΠΉΠ½ Π½Π° IM
ΠΡΡΠ²ΠΎ, ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌ ΠΊΠ°ΠΊ ΡΠ΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° Π½Π°ΡΠΈΡΡ IM. ΠΠ° ΠΏΡΠΎΡΡΠΎΡΠ°, Π½Π΅ΠΊΠ° Π±ΡΠ΄Π΅ peer-to-peer ΠΌΡΠ΅ΠΆΠ°, Π±Π΅Π· ΠΎΡΠΊΡΠΈΠ²Π°Π½Π΅ Π½Π° ΡΡΠ°ΡΡΠ½ΠΈΡΠΈΡΠ΅. Π ΡΡΠ½ΠΎ ΡΠ΅ ΠΏΠΎΡΠΎΡΠ²Π°ΠΌΠ΅ Π½Π° ΠΊΠ°ΠΊΡΠ² Π°Π΄ΡΠ΅Ρ: ΠΏΠΎΡΡ Π΄Π° ΡΠ΅ ΡΠ²ΡΡΠ·Π²Π°ΠΌΠ΅ Π·Π° ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡ Ρ ΡΠ°Π·Π³ΠΎΠ²ΠΎΡΠ°.
Π Π°Π·Π±ΠΈΡΠ°ΠΌ, ΡΠ΅ Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Π·Π° Π½Π°Π»ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° Π΄ΠΈΡΠ΅ΠΊΡΠ½Π° Π²ΡΡΠ·ΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΈ ΠΊΠΎΠΌΠΏΡΡΡΡΠ° Π΅ ΡΡΡΠ΅ΡΡΠ²ΠΈΡΠ΅Π»Π½ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ Π·Π° ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈΡ IM. ΠΠΎ ΠΊΠΎΠ»ΠΊΠΎΡΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈ ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°Ρ Π²ΡΡΠΊΠ°ΠΊΠ²ΠΈ NAT-ΡΡΠ°Π²Π΅ΡΡ ΠΊΠ°ΠΏΠ°Π½ΠΈ, ΡΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΠΎ-Π΄ΡΠ»Π³ΠΎ ΡΠ΅ ΠΎΡΡΠ°Π½Π΅ΠΌ Π² IPv4 ΠΈΠ½ΡΠ΅ΡΠ½Π΅Ρ Ρ ΡΠ°Π·ΠΎΡΠ°ΡΠΎΠ²Π°ΡΠ°ΡΠ° Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡ Π·Π° Π²ΡΡΠ·ΠΊΠ° ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΈ ΠΊΠΎΠΌΠΏΡΡΡΠΈ. ΠΠ°ΠΊ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠΎΠ»Π΅ΡΠΈΡΠ°ΠΌΠ΅ ΠΎΡΡΡΡΡΠ²ΠΈΠ΅ΡΠΎ Π½Π° IPv6 Ρ Π΄ΠΎΠΌΠ° ΠΈ Π½Π° ΡΠ°Π±ΠΎΡΠ°?
Π©Π΅ ΠΈΠΌΠ°ΠΌΠ΅ friend-to-friend ΠΌΡΠ΅ΠΆΠ°: Π²ΡΠΈΡΠΊΠΈ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΈ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΡΠΈ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ° ΠΈΠ·Π²Π΅ΡΡΠ½ΠΈ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»Π½ΠΎ. ΠΡΡΠ²ΠΎ, ΡΠΎΠ²Π° Π·Π½Π°ΡΠΈΡΠ΅Π»Π½ΠΎ ΡΠ»Π΅ΡΠ½ΡΠ²Π° Π²ΡΠΈΡΠΊΠΎ: ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΡΠΌΠ΅ ΡΠ΅, Π½Π°ΠΌΠΈΡΠ°ΠΌΠ΅ ΠΈΠ»ΠΈ Π½Π΅ Π½Π°ΠΌΠΈΡΠ°ΠΌΠ΅ ΠΈΠΌΠ΅/ΠΊΠ»ΡΡ, ΠΎΡΠΊΠ»ΡΡΠ²Π°ΠΌΠ΅ ΠΈΠ»ΠΈ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ°Π²Π°ΠΌΠ΅ ΡΠ°Π±ΠΎΡΠ°, Π·Π½Π°Π΅ΠΉΠΊΠΈ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°. ΠΡΠΎΡΠΎ, ΠΏΠΎ ΠΏΡΠΈΠ½ΡΠΈΠΏ, ΡΠΎΠ²Π° Π΅ ΡΠΈΠ³ΡΡΠ½ΠΎ ΠΈ ΠΈΠ·ΠΊΠ»ΡΡΠ²Π° ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π°ΡΠ°ΠΊΠΈ.
ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡΡ Π½Π° IM-Π° ΡΠ΅ Π±ΡΠ΄Π΅ Π±Π»ΠΈΠ·ΡΠΊ Π΄ΠΎ ΠΊΠ»Π°ΡΠΈΡΠ΅ΡΠΊΠΈΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΡ. , ΠΊΠΎΠΈΡΠΎ ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠΈ Ρ Π°ΡΠ΅ΡΠ²Π°Ρ Π·Π°ΡΠ°Π΄ΠΈ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΠΈΠ·ΠΌΠ° ΡΠΈ ΠΈ ΡΠΈΠ»ΠΎΡΠΎΡΠΈΡΡΠ° Π½Π° Unix-way. IM ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° Π·Π° Π²ΡΠ΅ΠΊΠΈ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ ΡΡΠ·Π΄Π°Π²Π° Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ Ρ ΡΡΠΈ Unix domain socket:
- in β Π² Π½Π΅Π³ΠΎ ΡΠ΅ Π·Π°ΠΏΠΈΡΠ²Π°Ρ ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½ΠΈΡΠ΅ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ;
- out β ΠΎΡ Π½Π΅Π³ΠΎ ΡΠ΅ ΡΠ΅ΡΠ°Ρ ΠΏΠΎΠ»ΡΡΠ°Π²Π°Π½ΠΈΡΠ΅ ΠΎΡ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ;
- state β ΡΠ΅ΡΠ΅ΠΉΠΊΠΈ ΠΎΡ Π½Π΅Π³ΠΎ, ΡΠ°Π·Π±ΠΈΡΠ°ΠΌΠ΅ Π΄Π°Π»ΠΈ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΡΡ Π΅ ΡΠ²ΡΡΠ·Π°Π½ Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ°, Π°Π΄ΡΠ΅Ρ/ΠΏΠΎΡΡ Π½Π° ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ΡΠΎ.
ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π°, ΡΠ΅ ΡΡΠ·Π΄Π°Π²Π° conn ΡΠΎΠΊΠ΅Ρ, Π·Π°ΠΏΠΈΡΠ²Π°ΠΉΠΊΠΈ Π² Π½Π΅Π³ΠΎ Ρ ΠΎΡΡ ΠΏΠΎΡΡΠ°, ΠΈΠ½ΠΈΡΠΈΠΈΡΠ°ΠΌΠ΅ ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ΡΠΎ Ρ ΠΎΡΠ΄Π°Π»Π΅ΡΠ΅Π½ΠΈΡ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ.
|-- alice
| |-- in
| |-- out
| `-- state
|-- bob
| |-- in
| |-- out
| `-- state
`- conn
Π’ΠΎΠ·ΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π½Π° IM ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ° ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΈΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, Π·Π°ΡΠΎΡΠΎ Π½Π° Π²ΠΊΡΡ ΠΈ ΡΠ²Π΅Ρ ΠΏΡΠΈΡΡΠ΅Π»ΠΈ Π½ΡΠΌΠ°, Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π΄Π° ΡΠ³ΠΎΠ΄ΠΈΡ Π½Π° Π²ΡΠΈΡΠΊΠΈ. ΠΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΠΈ/ΠΈΠ»ΠΈ , ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠ°Π½Π΅Π»Π΅Π½ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ½Π° ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠ°. Π Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΡΠ²ΠΌΠ΅ΡΡΠΈΠΌ ΡΠ΅Π΄ Π·Π° Π²ΡΠ²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Ρ GNU Readline.
ΠΡΡΡΠ½ΠΎΡΡ, ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠ΅ Π½Π° suckless ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ FIFO-ΡΠ°ΠΉΠ»ΠΎΠ²Π΅. ΠΠΈΡΠ½ΠΎ Π°Π· Π½Π΅ ΡΡΠΏΡΡ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ° ΠΊΠ°ΠΊ Π΄Π° ΡΠ°Π±ΠΎΡΡ Ρ ΡΠ°ΠΉΠ»ΠΎΠ²Π΅ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΠΎ Π² asyncio Π±Π΅Π· ΡΡΡΠ½ΠΎ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°Π½Π΅ ΠΎΡ ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΈ Π½ΠΈΡΠΊΠΈ (Π·Π° ΡΠ°ΠΊΠΈΠ²Π° Π½Π΅ΡΠ° ΠΎΡΠ΄Π°Π²Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Π΅Π·ΠΈΠΊ ). ΠΠ°ΡΠΎΠ²Π° ΡΠ΅ΡΠΈΡ Π΄Π° ΡΠ΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ°Π²Π°ΠΌ Ρ Unix domain ΡΠΎΠΊΠ΅ΡΠΈ. ΠΠ° ΡΡΠΆΠ°Π»Π΅Π½ΠΈΠ΅, ΡΠΎΠ²Π° Π»ΠΈΡΠ°Π²Π° Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π΄Π° ΡΠ΅ Π½Π°ΠΏΡΠ°Π²ΠΈ echo 2001:470:dead::babe 6666 > conn. Π Π΅ΡΠΈΡ ΡΠΎΠ·ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ : echo 2001:470:dead::babe 6666 | socat β UNIX-CONNECT:conn, socat READLINE UNIX-CONNECT:alice/in.
ΠΡΡΠ²ΠΎΠ½Π°ΡΠ°Π»Π΅Π½ Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ΅Π½ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»
ΠΠ°ΡΠΎ ΡΡΠ°Π½ΡΠΏΠΎΡΡ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° TCP: ΡΠΎΠΉ Π³Π°ΡΠ°Π½ΡΠΈΡΠ° Π΄ΠΎΡΡΠ°Π²ΠΊΠ°ΡΠ° ΠΈ ΡΠ΅Π΄Π° Ρ. UDP Π½Π΅ Π³Π°ΡΠ°Π½ΡΠΈΡΠ° Π½ΠΈΡΠΎ Π΅Π΄Π½ΠΎ ΠΎΡ Π΄Π²Π΅ΡΠ΅ (ΠΊΠΎΠ΅ΡΠΎ Π±ΠΈ Π±ΠΈΠ»ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, ΠΊΠΎΠ³Π°ΡΠΎ ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠΈ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ), Π° ΠΏΠΎΠ΄Π΄ΡΡΠΆΠΊΠ°ΡΠ° Π½Π° Π² Python ΠΎΡ ΠΊΡΡΠΈΡΡΠ° Ρ Π½ΡΠΌΠ°.
ΠΠ° ΡΡΠΆΠ°Π»Π΅Π½ΠΈΠ΅, Π² TCP Π½ΡΠΌΠ° ΠΊΠΎΠ½ΡΠ΅ΠΏΡΠΈΡ Π·Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, Π° ΡΠ°ΠΌΠΎ ΠΏΠΎΡΠΎΠΊ ΠΎΡ Π±Π°ΠΉΡΠΎΠ²Π΅. ΠΠ°ΡΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΠΈΠ·ΠΌΠΈΡΠ»ΠΈΠΌ ΡΠΎΡΠΌΠ°Ρ Π·Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ, Π·Π° Π΄Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π³ΠΈ ΡΠ°Π·Π΄Π΅Π»ΡΠΌΠ΅ Π² ΡΠΎΠ·ΠΈ ΠΏΠΎΡΠΎΠΊ. ΠΠΎΠΆΠ΅ΠΌ Π΄Π° ΡΠ΅ ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΡΠΈΠΌΠ²ΠΎΠ» Π·Π° Π½ΠΎΠ² ΡΠ΅Π΄. ΠΠ° Π½Π°ΡΠ°Π»ΠΎ ΡΠ΅ Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΎ, Π½ΠΎ ΠΊΠΎΠ³Π°ΡΠΎ Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌ Π΄Π° ΠΊΡΠΈΠΏΡΠΈΡΠ°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° ΡΠΈ, ΡΠΎΠ·ΠΈ ΡΠΈΠΌΠ²ΠΎΠ» ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΏΠΎΡΠ²ΠΈ Π½Π°Π²ΡΡΠΊΡΠ΄Π΅ Π² ΠΊΡΠΈΠΏΡΠΎΡΠ΅ΠΊΡΡΠ°. Π ΠΌΡΠ΅ΠΆΠΈΡΠ΅ Π·Π°ΡΠΎΠ²Π° ΡΠ° ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΏΡΡΠ²ΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠ°Ρ Π΄ΡΠ»ΠΆΠΈΠ½Π°ΡΠ° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Π² Π±Π°ΠΉΡΠΎΠ²Π΅. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Python ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ ΠΈΠΌΠ° xdrlib, ΠΊΠΎΡΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° ΡΠ°Π±ΠΎΡΠ° Ρ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ ΡΠΎΡΠΌΠ°Ρ. .
ΠΡΠΌΠ° Π΄Π° ΡΠ°Π±ΠΎΡΠΈΠΌ ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΎ ΠΈ Π΅ΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΡΡΡ ΡΠ΅ΡΠ΅Π½Π΅ΡΠΎ ΠΎΡ TCP β ΡΠ΅ ΠΎΠΏΡΠΎΡΡΠΈΠΌ ΠΊΠΎΠ΄Π°. Π§Π΅ΡΠ΅ΠΌ Π² Π±Π΅Π·ΠΊΡΠ°Π΅Π½ ΡΠΈΠΊΡΠ» Π΄Π°Π½Π½ΠΈ ΠΎΡ ΡΠΎΠΊΠ΅ΡΠ°, Π΄ΠΎΠΊΠ°ΡΠΎ Π½Π΅ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°ΠΌΠ΅ ΠΏΡΠ»Π½ΠΎΡΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅. ΠΠ°ΡΠΎ ΡΠΎΡΠΌΠ°Ρ Π·Π° ΡΠΎΠ·ΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΈ JSON Ρ XML. ΠΠΎ, ΠΊΠΎΠ³Π°ΡΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ, Π΄Π°Π½Π½ΠΈΡΠ΅ ΡΠ΅ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π°Ρ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½ΠΈ ΠΈ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠ°Π½ΠΈ β Π° ΡΠΎΠ²Π° ΡΠ΅ ΠΈΠ·ΠΈΡΠΊΠ²Π° Π±Π°ΠΉΡ-Π²-Π±Π°ΠΉΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΡΠ½Π΅ Π½Π° ΠΎΠ±Π΅ΠΊΡΠΈΡΠ΅, ΠΊΠΎΠ΅ΡΠΎ JSON/XML Π½Π΅ ΠΎΡΠΈΠ³ΡΡΡΠ²Π°Ρ (Π³ΠΎΡΠΎΠ²ΠΈΡΡ ΡΠ΅Π·ΡΠ»ΡΠ°Ρ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ°Π·Π»ΠΈΡΠ°Π²Π°).
XDR Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡ Π·Π° ΡΠ°Π·ΠΈ Π·Π°Π΄Π°ΡΠ°, Π½ΠΎ Π°Π· ΠΈΠ·Π±ΠΈΡΠ°ΠΌ ASN.1 Ρ DER-ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ°, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠ΅ ΡΠ°Π·ΠΏΠΎΠ»Π°Π³Π°ΠΌΠ΅ Ρ Π²ΠΈΡΠΎΠΊΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΈ ΠΎΠ±Π΅ΠΊΡΠΈ, Ρ ΠΊΠΎΠΈΡΠΎ ΡΠ΅ΡΡΠΎ Π΅ ΠΏΠΎ-ΠΏΡΠΈΡΡΠ½ΠΎ ΠΈ ΡΠ΄ΠΎΠ±Π½ΠΎ Π΄Π° ΡΠ°Π±ΠΎΡΠΈΠΌ. Π ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ Π±Π΅Π·ΡΡ Π΅ΠΌΠ½ΠΈ , ΠΈΠ»ΠΈ , ASN.1 Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΠΈ Π΄Π°Π½Π½ΠΈΡΠ΅ ΡΡΠ΅ΡΡ ΡΡΡΠΎΠ³ΠΎ Π·Π°Π΄Π°Π΄Π΅Π½Π° ΡΡ Π΅ΠΌΠ°.
# 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))),
))
ΠΡΠΈΠ΅ΠΌΠ°Π½ΠΎΡΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΡΠ΅ Π±ΡΠ΄Π΅ Msg: ΠΈΠ»ΠΈ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎ MsgText (Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° Ρ Π΅Π΄Π½ΠΎ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎ ΠΏΠΎΠ»Π΅), ΠΈΠ»ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π·Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅ MsgHandshake (Π² ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ ΠΏΡΠ΅Π΄Π°Π²Π° ΠΈΠΌΠ΅ΡΠΎ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°). Π ΠΌΠΎΠΌΠ΅Π½ΡΠ° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΡΠ΅ΠΊΠ°Π»Π΅Π½ΠΎ ΡΠ»ΠΎΠΆΠ½ΠΎ, Π½ΠΎ ΡΠΎΠ²Π° Π΅ ΠΎΡΠ½ΠΎΠ²Π° Π·Π° Π±ΡΠ΄Π΅ΡΠ΅ΡΠΎ.
βββββββ βββββββ
βPeerAβ βPeerBβ
ββββ¬βββ ββββ¬βββ
βMsgHandshake(IdA) β
ββββββββββββββββββ>β
β β
βMsgHandshake(IdB) β
ββ
β β
β MsgText() β
β<ββββββββββββββββββ
β β
IM Π±Π΅Π· ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ
ΠΠ°ΠΊΡΠΎ Π²Π΅ΡΠ΅ ΠΊΠ°Π·Π°Ρ , Π·Π° Π²ΡΠΈΡΠΊΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΡΡΡ ΡΠΎΠΊΠ΅ΡΠΈ ΡΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° asyncio. ΠΠ° ΠΎΠ±ΡΠ²ΠΈΠΌ ΠΊΠ°ΠΊΠ²ΠΎ ΠΎΡΠ°ΠΊΠ²Π°ΠΌΠ΅ Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅:
parser = argparse.ArgumentParser(description="GOSTIM")
parser.add_argument(
"--our-name",
required=True,
help="ΠΠ°ΡΠ΅ΡΠΎ ΠΈΠΌΠ΅ Π½Π° Π²ΡΡΡΡΠ½ΠΈΠΊΠ°",
)
parser.add_argument(
"--their-names",
required=True,
help="ΠΠ°ΠΌΠΈ Π½Π° Π²ΡΡΡΡΠ½ΠΈΡΠΈΡΠ΅, ΡΠ°Π·Π΄Π΅Π»Π΅Π½ΠΈ Ρ Π·Π°ΠΏΠ΅ΡΠ°Ρ",
)
parser.add_argument(
"--bind",
default="::1",
help="ΠΠ΄ΡΠ΅Ρ Π·Π° ΡΠ»ΡΡΠ°Π½Π΅",
)
parser.add_argument(
"--port",
type=int,
default=6666,
help="ΠΠΎΡΡ Π·Π° ΡΠ»ΡΡΠ°Π½Π΅",
)
args = parser.parse_args()
OUR_NAME = UTF8String(args.our_name)
THEIR_NAMES = set(args.their_names.split(","))
ΠΠ°Π΄Π°Π²Π° ΡΠ΅ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΎ ΠΈΠΌΠ΅ (βour-name alice). Π§ΡΠ΅Π· Π·Π°ΠΏΠ΅ΡΠ°Ρ ΡΠ΅ ΠΈΠ·Π±ΡΠΎΡΠ²Π°Ρ Π²ΡΠΈΡΠΊΠΈ ΠΎΡΠ°ΠΊΠ²Π°Π½ΠΈ ΡΠ°Π·Π³ΠΎΠ²ΠΎΡΠ½ΠΈΡΠΈ (βtheir-names bob,eve). ΠΠ° Π²ΡΠ΅ΠΊΠΈ ΠΎΡ ΡΠ°Π·Π³ΠΎΠ²ΠΎΡΠ½ΠΈΡΠΈΡΠ΅ ΡΠ΅ ΡΡΠ·Π΄Π°Π²Π° Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ Ρ Unix ΡΠΎΠΊΠ΅ΡΠΈ, Π° ΡΡΡΠΎ ΡΠ°ΠΊΠ° ΠΈ ΠΊΠΎΡΡΡΠΈΠ½Π° Π·Π° Π²ΡΠ΅ΠΊΠΈ in, out, state:
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"))
ΠΡΠΈΡ ΠΎΠ΄ΡΡΠΈΡΠ΅ ΠΎΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΡ in ΡΠΎΠΊΠ΅ΡΠ° ΡΠ΅ ΠΈΠ·ΠΏΡΠ°ΡΠ°Ρ Π² 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"))
ΠΡΠΈΡ ΠΎΠ΄ΡΡΠΈΡΠ΅ ΠΎΡ ΡΠ°Π·Π³ΠΎΠ²ΠΎΡΠ½ΠΈΡΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΠ΅ ΠΈΠ·ΠΏΡΠ°ΡΠ°Ρ Π² OUT_QUEUES ΠΎΠΏΠ°ΡΠΊΠΈΡΠ΅, ΠΎΡ ΠΊΠΎΠΈΡΠΎ Π΄Π°Π½Π½ΠΈΡΠ΅ ΡΠ΅ Π·Π°ΠΏΠΈΡΠ²Π°Ρ Π² out ΡΠΎΠΊΠ΅ΡΠ°:
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()
ΠΡΠΈ ΡΠ΅ΡΠ΅Π½Π΅ ΠΎΡ state ΡΠΎΠΊΠ΅ΡΠ°, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΡΡΡΡΠΈ Π² PEER_ALIVE ΡΠ΅ΡΠ½ΠΈΠΊΠ° Π°Π΄ΡΠ΅ΡΠ° Π½Π° ΡΠ°Π·Π³ΠΎΠ²ΠΎΡΠ½ΠΈΠΊΠ°. ΠΠΊΠΎ Π½ΡΠΌΠ° ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ Ρ ΡΠ°Π·Π³ΠΎΠ²ΠΎΡΠ½ΠΈΠΊΠ°, Π·Π°ΠΏΠΈΡΠ²Π° ΡΠ΅ ΠΏΡΠ°Π·Π΅Π½ Π½ΠΈΠ·.
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()
ΠΡΠΈ Π·Π°ΠΏΠΈΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° Π°Π΄ΡΠ΅ΡΠ° Π² conn ΡΠΎΠΊΠ΅ΡΠ° ΡΡΠ°ΡΡΠΈΡΠ° ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π½Π° βΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ°β Π½Π° ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ΡΠΎ:
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))
ΠΠ΅ΠΊΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ°. ΠΡΡΠ²ΠΎ, ΡΠΎΠΉ ΠΎΡΠΊΡΠΈΠ²Π° ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ ΠΊΡΠΌ ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈΡ Ρ ΠΎΡΡ/ΠΏΠΎΡΡ ΠΈ ΠΈΠ·ΠΏΡΠ°ΡΠ° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π·Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅ Ρ ΠΈΠΌΠ΅ΡΠΎ ΡΠΈ:
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()
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΠΈΠ·ΡΠ°ΠΊΠ²Π° ΠΎΡΠ³ΠΎΠ²ΠΎΡ ΠΎΡ ΠΎΡΠ΄Π°Π»Π΅ΡΠ΅Π½Π°ΡΠ° ΡΡΡΠ°Π½Π°. ΠΠΏΠΈΡΠ²Π° ΡΠ΅ Π΄Π° Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ° ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡΠ΅ Π΄Π°Π½Π½ΠΈ ΠΏΠΎ ΡΡ Π΅ΠΌΠ°ΡΠ° Msg ASN.1. ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌ, ΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΈΠ·ΠΏΡΠ°ΡΠ΅Π½ΠΎ Π² Π΅Π΄ΠΈΠ½ TCP ΡΠ΅Π³ΠΌΠ΅Π½Ρ ΠΈ ΡΠ΅ Π³ΠΎ ΠΏΠΎΠ»ΡΡΠΈΠΌ Π² Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎ ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ ΠΏΡΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° .read(). ΠΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ Π΄Π°Π»ΠΈ Π½Π°ΠΈΡΡΠΈΠ½Π° ΡΠΌΠ΅ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π·Π° handshake.
141 # ΠΠ·ΡΠ°ΠΊΠ²Π°Π½Π΅ Π½Π° Handshake ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ {{{
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 # }}}
ΠΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ Π΄Π°Π»ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎΡΠΎ ΠΈΠΌΠ΅ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° Π½ΠΈ Π΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ. ΠΠΊΠΎ Π½Π΅ Π΅, ΠΏΡΠ΅ΠΊΡΡΠ²Π°ΠΌΠ΅ Π²ΡΡΠ·ΠΊΠ°ΡΠ°. ΠΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ Π΄Π°Π»ΠΈ Π²Π΅ΡΠ΅ ΠΈΠΌΠ°ΠΌΠ΅ ΡΡΡΠ°Π½ΠΎΠ²Π΅Π½Π° Π²ΡΡΠ·ΠΊΠ° Ρ Π½Π΅Π³ΠΎ (ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΡΡ ΠΎΡΠ½ΠΎΠ²ΠΎ Π΅ ΠΏΠΎΠ΄Π°Π» ΠΊΠΎΠΌΠ°Π½Π΄Π° Π·Π° ΡΠ²ΡΡΠ·Π²Π°Π½Π΅) ΠΈ Ρ Π·Π°ΡΠ²Π°ΡΡΠΌΠ΅. Π IN_QUEUES ΡΠ΅ ΠΏΠΎΡΡΠ°Π²ΡΡ Python Π½ΠΈΠ·ΠΎΠ²Π΅ Ρ ΡΠ΅ΠΊΡΡΠ° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ, Π½ΠΎ ΠΈΠΌΠ° ΠΎΡΠΎΠ±Π΅Π½Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ None, ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΡΠ° Π½Π° ΠΊΠΎΡΡΡΠΈΠ½Π°ΡΠ° msg_sender Π΄Π° ΡΠΏΡΠ΅ ΡΠ°Π±ΠΎΡΠ°, Π·Π° Π΄Π° Π·Π°Π±ΡΠ°Π²ΠΈ Π·Π° ΡΠ²ΠΎΡ writer, ΡΠ²ΡΡΠ·Π°Π½ Ρ ΠΎΡΡΠ°ΡΡΠ»ΠΎΡΠΎ TCP ΡΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅.
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 # Π‘ΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°ΡΠ° Π½Π° ΡΠ΅ΠΊΡΡΠΎΠ²ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π½Π° Π΄Π΅ΠΊΠΎΠ΄Π΅ΡΠ° Π½Π° ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ° {{{
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 ΠΏΡΠΈΠ΅ΠΌΠ° ΠΈΠ·Ρ ΠΎΠ΄ΡΡΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ (ΠΏΠΎΡΡΠ°Π²Π΅Π½ΠΈ Π² ΠΎΠΏΠ°ΡΠΊΠ°ΡΠ° ΠΎΡ Π²Ρ ΠΎΠ΄ΡΡΠΈΡ ΡΠΎΠΊΠ΅Ρ), ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ° Π³ΠΈ Π² ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ MsgText ΠΈ Π³ΠΈ ΠΈΠ·ΠΏΡΠ°ΡΠ° ΠΏΠΎ TCP ΡΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ΡΠΎ. Π’ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡΠ΅ΠΊΡΡΠ½Π΅ ΠΏΠΎ Π²ΡΡΠΊΠΎ Π²ΡΠ΅ΠΌΠ΅ β ΠΊΠΎΠ΅ΡΠΎ ΠΈΠ·ΡΠΈΡΠ½ΠΎ ΡΠ»ΠΎΠ²ΡΠ²Π°ΠΌΠ΅.
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))
Π ΠΊΡΠ°Ρ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΡΡ Π²Π»ΠΈΠ·Π° Π² Π±Π΅Π·ΠΊΡΠ°Π΅Π½ ΡΠΈΠΊΡΠ» Π·Π° ΡΠ΅ΡΠ΅Π½Π΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΡ ΡΠΎΠΊΠ΅ΡΠ°. ΠΡΠΎΠ²Π΅ΡΡΠ²Π° Π΄Π°Π»ΠΈ ΡΠ° ΡΠ΅ΠΊΡΡΠΎΠ²ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΈ Π³ΠΈ ΠΏΠΎΡΡΠ°Π²Ρ Π² OUT_QUEUES ΠΎΠΏΠ°ΡΠΊΠ°ΡΠ°, ΠΎΡΠΊΡΠ΄Π΅ΡΠΎ ΡΠ΅ Π±ΡΠ΄Π°Ρ ΠΈΠ·ΠΏΡΠ°ΡΠ΅Π½ΠΈ Π² ΠΈΠ·Ρ ΠΎΠ΄Π½ΠΈΡ ΡΠΎΠΊΠ΅Ρ Π½Π° ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ. ΠΠ°ΡΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΎΡΡΠΎ Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ .read() ΠΈ Π΄Π° Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ? ΠΠ°ΡΠΎΡΠΎ Π½Π΅ Π΅ ΠΈΠ·ΠΊΠ»ΡΡΠ΅Π½Π° ΡΠΈΡΡΠ°ΡΠΈΡΡΠ°, Π² ΠΊΠΎΡΡΠΎ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΡΠ° Π°Π³ΡΠ΅Π³ΠΈΡΠ°Π½ΠΈ Π² Π±ΡΡΠ΅ΡΠ° Π½Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½Π°ΡΠ° ΡΠΈΡΡΠ΅ΠΌΠ° ΠΈ ΠΈΠ·ΠΏΡΠ°ΡΠ΅Π½ΠΈ Π² Π΅Π΄ΠΈΠ½ TCP ΡΠ΅Π³ΠΌΠ΅Π½Ρ. Π©Π΅ ΡΡΠΏΠ΅Π΅ΠΌ Π΄Π° Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°ΠΌΠ΅ ΠΏΡΡΠ²ΠΎΡΠΎ, Π° Π² Π±ΡΡΠ΅ΡΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΡΡΠ°Π½Π΅ ΡΠ°ΡΡ ΠΎΡ ΡΠ»Π΅Π΄Π²Π°ΡΠΎΡΠΎ. ΠΡΠΈ Π²ΡΡΠΊΠ° ΠΈΠ·Π²ΡΠ½ΡΠ΅Π΄Π½Π° ΡΠΈΡΡΠ°ΡΠΈΡ Π·Π°ΡΠ²Π°ΡΡΠΌΠ΅ TCP Π²ΡΡΠ·ΠΊΠ°ΡΠ° ΠΈ ΡΠΏΠΈΡΠ°ΠΌΠ΅ msg_sender ΠΊΠΎΡΡΡΠΈΠ½Π°ΡΠ° (ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΉΠΊΠΈ None Π² OUT_QUEUES ΠΎΠΏΠ°ΡΠΊΠ°ΡΠ°).
174 buf = b""
175 # ΠΠ·ΡΠ°ΠΊΠ°ΠΉΡΠ΅ ΡΠ΅ΡΡΠΎΠ²ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ {{{
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: ΠΏΡΠ΅Π²ΠΈΡΠ΅Π½Π° ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π° Π½Π° Π±ΡΡΠ΅ΡΠ°", _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: Π½Π΅ΠΎΡΠ°ΠΊΠ²Π°Π½ΠΎ %s ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅", _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: ΠΏΡΠ΅ΠΊΡΡΠ²Π° Π²ΡΡΠ·ΠΊΠ°ΡΠ°: %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: ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Ρ %d Π·Π½Π°ΠΊΠ°", peer_name, len(text))
69 await OUT_QUEUES[peer_name].put(text)
ΠΠ΅ΠΊΠ° ΡΠ΅ Π²ΡΡΠ½Π΅ΠΌ ΠΊΡΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡ ΠΊΠΎΠ΄. Π‘Π»Π΅Π΄ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° Π²ΡΠΈΡΠΊΠΈ ΠΊΠΎΡΡΡΠΈΠ½ΠΈ Π² ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π½Π° ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΡΡΠ°ΡΡΠΈΡΠ°ΠΌΠ΅ TCP ΡΡΡΠ²ΡΡ. ΠΠ° Π²ΡΡΠΊΠ° ΡΡΡΠ°Π½ΠΎΠ²Π΅Π½Π° Π²ΡΡΠ·ΠΊΠ° ΡΠΎΠΉ ΡΡΠ·Π΄Π°Π²Π° responder (ΠΎΡΠ³ΠΎΠ²ΠΎΡΠ½ΠΈΠΊ) ΠΊΠΎΡΡΡΠΈΠ½Π°.
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("Π‘Π»ΡΡΠ°Π½Π΅ Π½Π°: %s", server.sockets[0].getsockname())
loop.run_forever()
responder Π΅ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ Π½Π° initiator ΠΈ Π·Π΅ΡΠΊΠ°Π»Π½ΠΎ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° Π²ΡΠΈΡΠΊΠΈ ΡΡΡΠΈΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, Π½ΠΎ Π±Π΅Π·ΠΊΡΠ°ΠΉΠ½ΠΈΡΡ ΡΠΈΠΊΡΠ» Π·Π° ΡΠ΅ΡΠ΅Π½Π΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΠ΅ ΡΡΠ°ΡΡΠΈΡΠ° Π²Π΅Π΄Π½Π°Π³Π°, Π·Π° ΠΏΠΎ-Π³ΠΎΠ»ΡΠΌΠ° ΠΏΡΠΎΡΡΠΎΡΠ°. Π ΠΌΠΎΠΌΠ΅Π½ΡΠ° ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΡΡ Π·Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅ ΠΈΠ·ΠΏΡΠ°ΡΠ° ΠΏΠΎ Π΅Π΄Π½ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΡ Π²ΡΡΠΊΠ° ΡΡΡΠ°Π½Π°, Π½ΠΎ Π²ΠΏΠΎΡΠ»Π΅Π΄ΡΡΠ²ΠΈΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΡΠ°ΡΠ° ΠΏΠΎ Π΄Π²Π΅ ΠΎΡ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ° Π½Π° Π²ΡΡΠ·ΠΊΠ°ΡΠ°, ΡΠ»Π΅Π΄ ΠΊΠΎΠ΅ΡΠΎ Π²Π΅Π΄Π½Π°Π³Π° Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΠ΅ΠΊΡΡΠΎΠ²ΠΈ.
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()
Π‘ΠΈΠ³ΡΡΠ΅Π½ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»
ΠΡΠ΅ΠΌΠ΅ Π΅ Π΄Π° ΠΎΡΠΈΠ³ΡΡΠΈΠΌ Π½Π°ΡΠ΅ΡΠΎ ΠΊΠΎΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡ. ΠΠ°ΠΊΠ²ΠΎ ΡΠ°Π·Π±ΠΈΡΠ°ΠΌΠ΅ ΠΏΠΎΠ΄ ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ ΠΈ ΠΊΠ°ΠΊΠ²ΠΎ ΠΈΡΠΊΠ°ΠΌΠ΅:
- ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»Π½ΠΎΡΡ Π½Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½ΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ;
- Π°Π²ΡΠ΅Π½ΡΠΈΡΠ½ΠΎΡΡ ΠΈ ΡΠ΅Π»ΠΎΡΡΠ½ΠΎΡΡ Π½Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½ΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ β Π²ΡΡΠΊΠ° ΠΏΡΠΎΠΌΡΠ½Π° ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΡΡΡΠ°Π½ΠΎΠ²Π΅Π½Π°;
- Π·Π°ΡΠΈΡΠ° ΠΎΡ Π°ΡΠ°ΠΊΠΈ Ρ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΈΠ·Π»ΡΡΠ²Π°Π½Π΅ (replay attack) β ΡΠ°ΠΊΡΡΡ Π·Π° Π·Π°Π³ΡΠ±Π° ΠΈΠ»ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ΅Π½ΠΈΠ΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΎΡΠΊΡΠΈΡ (ΠΈ ΡΠ΅ΡΠ°Π²Π°ΠΌΠ΅ Π΄Π° ΠΏΡΠ΅ΠΊΡΡΠ½Π΅ΠΌ Π²ΡΡΠ·ΠΊΠ°ΡΠ°);
- ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΈ Π°Π²ΡΠ΅Π½ΡΠΈΠΊΠ°ΡΠΈΡ Π½Π° ΡΡΠ°ΡΡΠ½ΠΈΡΠΈΡΠ΅ ΠΏΠΎ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»Π½ΠΎ Π·Π°Π΄Π°Π΄Π΅Π½ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅ β Π²Π΅ΡΠ΅ ΡΠ΅ΡΠΈΡ ΠΌΠ΅, ΡΠ΅ ΡΡΠ·Π΄Π°Π²Π°ΠΌΠ΅ peer-to-peer ΠΌΡΠ΅ΠΆΠ°. Π‘Π°ΠΌΠΎ ΡΠ»Π΅Π΄ Π°Π²ΡΠ΅Π½ΡΠΈΠΊΠ°ΡΠΈΡ ΡΠ΅ ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌ Ρ ΠΊΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ²Π°ΠΌΠ΅;
- Π½Π°Π»ΠΈΡΠΈΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²Π° (PFS) β ΠΊΠΎΠΌΠΏΡΠΎΠΌΠ΅ΡΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° Π½Π°ΡΠΈΡ Π΄ΡΠ»Π³ΠΎΡΡΠΎΡΠ΅Π½ ΠΊΠ»ΡΡ Π·Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠΈ Π½Π΅ ΡΡΡΠ±Π²Π° Π΄Π° Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ Π·Π° ΡΠ΅ΡΠ΅Π½Π΅ Π½Π° ΠΏΡΠ΅Π΄ΠΈΡΠ½Π°ΡΠ° ΠΊΠΎΡΠ΅ΡΠΏΠΎΠ½Π΄Π΅Π½ΡΠΈΡ. ΠΠ°ΠΏΠΈΡΡΡ Π½Π° ΠΏΡΠΈΡ Π²Π°Π½Π°ΡΠΈΡ ΡΡΠ°ΡΠΈΠΊ ΡΡΠ°Π²Π° Π±Π΅Π·ΠΏΠΎΠ»Π΅Π·Π΅Π½;
- Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡΡΠ° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° (ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΠΈΡΠ΅ ΠΈ Π·Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅) Π²Π°ΠΆΠΈ ΡΠ°ΠΌΠΎ Π² ΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΠ΅ Π½Π° Π΅Π΄Π½Π° TCP ΡΠ΅ΡΠΈΡ. ΠΠΌΡΠΊΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΡΠ°Π²ΠΈΠ»Π½ΠΎ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½ΠΈ/Π°Π²ΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠ°Π½ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΡ Π΄ΡΡΠ³Π° ΡΠ΅ΡΠΈΡ (Π΄ΠΎΡΠΈ Ρ ΡΠΎΠ·ΠΈ ΡΡΡΠΈΡ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ) Π½Π΅ ΡΡΡΠ±Π²Π° Π΄Π° Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ;
- ΠΏΠ°ΡΠΈΠ²Π½ΠΈΡΡ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π» Π½Π΅ ΡΡΡΠ±Π²Π° Π΄Π° Π²ΠΈΠΆΠ΄Π° Π½ΠΈΡΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΈ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ, Π½ΠΈΡΠΎ ΠΏΡΠ΅Π΄Π°Π²Π°Π½ΠΈ Π΄ΡΠ»Π³ΠΎΡΡΠΎΡΠ½ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅, Π½ΠΈΡΠΎ Ρ Π΅ΡΠΎΠ²Π΅ ΠΎΡ ΡΡΡ . ΠΡΠΊΠ°ΠΊΠ²Π° Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΡΡ ΠΎΡ ΠΏΠ°ΡΠΈΠ²Π½ΠΈΡ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π».
Π£Π΄ΠΈΠ²ΠΈΡΠ΅Π»Π½ΠΎ, Π½ΠΎ ΡΠΎΠ·ΠΈ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ΅ΠΊΠΈ ΠΈΡΠΊΠ° Π΄Π° ΠΈΠΌΠ° Π² ΠΊΠΎΠΉΡΠΎ ΠΈ Π΄Π° Π΅ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Π·Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠ°Π»ΠΊΠΎ ΠΎΡ ΠΈΠ·Π±ΡΠΎΠ΅Π½ΠΎΡΠΎ Π² ΠΊΡΠ°ΠΉΠ½Π° ΡΠΌΠ΅ΡΠΊΠ° ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° Π·Π° "Π΄ΠΎΠΌΠ°ΡΠ½ΠΎ" ΡΡΠ·Π΄Π°Π΄Π΅Π½ΠΈΡΠ΅ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ. Π ΡΠ΅Π³Π°, Π΄Π° Π½Π΅ ΠΈΠ·ΠΌΠΈΡΠ»ΡΠΌΠ΅ Π½ΠΎΠ²ΠΎ. ΠΠ· Π±ΠΈΡ Π²ΠΈ ΠΏΡΠ΅ΠΏΠΎΡΡΡΠ°Π» Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ Π·Π° ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈ, Π½ΠΎ Π½Π΅ΠΊΠ° ΠΈΠ·Π±Π΅ΡΠ΅ΠΌ Π½Π΅ΡΠΎ ΠΏΠΎ-ΠΏΡΠΎΡΡΠΎ.
ΠΠ°ΠΉ-ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΈ ΡΠ° Π΄Π²Π° ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°:
- β Π½Π°ΠΉ-ΡΠ»ΠΎΠΆΠ½ΠΈΡΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Ρ Π΄ΡΠ»Π³Π° ΠΈΡΡΠΎΡΠΈΡ Π½Π° Π±ΡΠ³ΠΎΠ²Π΅, ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ, ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ, Π»ΠΎΡΠΎ ΠΎΠ±ΠΌΠΈΡΠ»ΡΠ½Π΅, ΡΠ»ΠΎΠΆΠ½ΠΎΡΠΈ ΠΈ ΠΏΡΠΎΠΏΡΡΠΊΠΈ (Π²ΡΠΏΡΠ΅ΠΊΠΈ ΡΠ΅ ΡΠΎΠ²Π° Π½Π΅ ΡΠ΅ ΠΎΡΠ½Π°ΡΡ Π΄ΠΎ TLS 1.3). ΠΠΎ Π½Π΅ Π³ΠΎ ΡΠ°Π·Π³Π»Π΅ΠΆΠ΄Π°ΠΌΠ΅ Π·Π°ΡΠ°Π΄ΠΈ ΠΏΡΠ΅ΠΊΠ°Π»Π΅Π½Π° ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ.
- Ρ β Π½ΡΠΌΠ°Ρ ΡΠ΅ΡΠΈΠΎΠ·Π½ΠΈ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΡΠΊΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ, Π²ΡΠΏΡΠ΅ΠΊΠΈ ΡΠ΅ ΡΡΡΠΎ Π½Π΅ ΡΠ° ΠΏΡΠΎΡΡΠΈ. ΠΠΊΠΎ ΠΏΡΠΎΡΠ΅ΡΠ΅ΡΠ΅ Π·Π° IKEv1 ΠΈ IKEv2, ΡΠ΅Ρ Π½ΠΈΡΡ ΠΏΡΠΎΠΈΠ·Ρ ΠΎΠ΄ ΡΠ° , ISO/IEC IS 9798-3 ΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈΡΠ΅ SIGMA (SIGn-and-MAc) β Π΄ΠΎΡΡΠ° ΠΏΡΠΎΡΡΠΈΡΠΊΠΈ Π·Π° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π·Π° Π΅Π΄ΠΈΠ½ Π²Π΅ΡΠ΅Ρ.
ΠΠ°ΠΊΠ²ΠΎ ΠΏΡΠ°Π²ΠΈ SIGMA, ΠΊΠ°ΡΠΎ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΎ Π·Π²Π΅Π½ΠΎ Π² ΡΠ°Π·Π²ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° STS/ISO ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΈΡΠ΅, Π΄ΠΎΠ±ΡΠΎ? Π’ΠΎΠΉ ΠΎΡΠ³ΠΎΠ²Π°ΡΡ Π½Π° Π²ΡΠΈΡΠΊΠΈΡΠ΅ Π½ΠΈ ΠΈΠ·ΠΈΡΠΊΠ²Π°Π½ΠΈΡ (Π²ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ "ΡΠΊΡΠΈΡΠΈΠ΅" Π½Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΈΡΠ΅ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΡΠΈΡΠ΅), Π½ΡΠΌΠ° ΠΈΠ·Π²Π΅ΡΡΠ½ΠΈ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΡΠΊΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ. Π’ΠΎΠΉ Π΅ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΠΈΡΡΠΈΡΠ΅Π½ β ΠΏΡΠ΅ΠΌΠ°Ρ Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΏΠΎΠ½Π΅ Π΅Π΄ΠΈΠ½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ ΠΎΡ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π° ΡΠ΅ Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ Π½Π΅Π³ΠΎΠ²Π°ΡΠ° Π½Π΅ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ.
ΠΠ΅ΠΊΠ° ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ΠΌ ΠΎΡ Π½Π°ΠΉ-ΠΏΡΠΎΡΡΠΈΡ Π΄ΠΎΠΌΠ°ΡΠ΅Π½ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Π΄ΠΎ SIGMA. ΠΠ°ΠΉ-ΠΎΡΠ½ΠΎΠ²Π½Π°ΡΠ° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ, ΠΊΠΎΡΡΠΎ Π½ΠΈ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ²Π°, Π΅ : ΡΡΠ½ΠΊΡΠΈΡ, ΠΏΡΠΈ ΠΊΠΎΡΡΠΎ ΠΈ Π΄Π²Π°ΠΌΠ°ΡΠ° ΡΡΠ°ΡΡΠ½ΠΈΡΠΈ ΠΏΠΎΠ»ΡΡΠ°Π²Π°Ρ Π΅Π΄Π½Π° ΠΈ ΡΡΡΠ° ΡΡΠΎΠΉΠ½ΠΎΡΡ, ΠΊΠΎΡΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΊΠ°ΡΠΎ ΡΠΈΠΌΠ΅ΡΡΠΈΡΠ΅Π½ ΠΊΠ»ΡΡ. ΠΠ΅Π· Π΄Π° Π½Π°Π²Π»ΠΈΠ·Π°ΠΌΠ΅ Π² ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ: Π²ΡΡΠΊΠ° ΠΎΡ ΡΡΡΠ°Π½ΠΈΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ° Π΅ΡΠΈΠΌΠ΅ΡΠ½Π° (ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π° ΡΠ°ΠΌΠΎ Π² ΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΠ΅ Π½Π° Π΅Π΄Π½Π° ΡΠ΅ΡΠΈΡ) ΠΊΠ»ΡΡΠΎΠ²Π° Π΄Π²ΠΎΠΉΠΊΠ° (ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ΠΈ ΡΠ°ΡΡΠ΅Π½ ΠΊΠ»ΡΡ), ΠΎΠ±ΠΌΠ΅Π½ΡΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅, ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ Π·Π° ΡΡΠ³Π»Π°ΡΡΠ²Π°Π½Π΅, Π½Π° Π²Ρ ΠΎΠ΄Π° Π½Π° ΠΊΠΎΡΡΠΎ ΠΏΠΎΠ΄Π°Π²Π°Ρ ΡΠ²ΠΎΡ ΡΠ°ΡΡΠ΅Π½ ΠΊΠ»ΡΡ ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡ ΠΊΠ»ΡΡ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°.
βββββββ βββββββ
βPeerAβ βPeerBβ
ββββ¬βββ ββββ¬βββ
β IdA, PubA β ββββββββββββββββββββββ
ββββββββββββββββ>β βPrvA, PubA = DHgen()β
β β ββββββββββββββββββββββ
β IdB, PubB β ββββββββββββββββββββββ
β<ββββββββββββββββ βPrvB, PubB = DHgen()β
β β ββββββββββββββββββββββ
βββββ βββββββββ§βββββββββββββ
β βKey = DH(PrvA, PubB)β
<ββββ βββββββββ€βββββββββββββ
β β
β β
ΠΡΠ΅ ΠΌΠΎΠ³Π°Ρ Π΄Π° ΡΠ΅ Π½Π°ΠΌΠ΅ΡΡΡ ΠΈ Π΄Π° Π·Π°ΠΌΠ΅Π½ΡΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π΅ ΡΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈΡΠ΅ ΡΠΈ β Π² ΡΠΎΠ·ΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Π½ΡΠΌΠ° Π°Π²ΡΠ΅Π½ΡΠΈΠΊΠ°ΡΠΈΡ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΡΠΈΡΠ΅. ΠΠ΅ΠΊΠ° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΠ΄ΠΏΠΈΡ Ρ Π΄ΡΠ»Π³ΠΎΡΡΠΎΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅.
βββββββ βββββββ
βPeerAβ βPeerBβ
ββββ¬βββ ββββ¬βββ
βIdA, PubA, sign(SignPrvA, (PubA)) β βββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββ>β βSignPrvA, SignPubA = load()β
β β βPrvA, PubA = DHgen() β
β β βββββββββββββββββββββββββββββ
βIdB, PubB, sign(SignPrvB, (PubB)) β βββββββββββββββββββββββββββββ
β<ββββββββββββββββββββββββββββββββββ βSignPrvB, SignPubB = load()β
β β βPrvB, PubB = DHgen() β
β β βββββββββββββββββββββββββββββ
βββββ βββββββββββββββββββββββ β
β βverify(SignPubB, ...)β β
<ββββ βKey = DH(PrvA, PubB) β β
β βββββββββββββββββββββββ β
β β
Π’Π°ΠΊΡΠ² ΠΏΠΎΠ΄ΠΏΠΈΡ Π½Π΅ Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡ, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π½Π΅ Π΅ ΡΠ²ΡΡΠ·Π°Π½ Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½Π° ΡΠ΅ΡΠΈΡ. Π’Π°ΠΊΡΠ² ΡΠΈΠΏ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΠ΅ βΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡβ ΠΈ Π·Π° ΡΠ΅ΡΠΈΠΈ Ρ Π΄ΡΡΠ³ΠΈ ΡΡΠ°ΡΡΠ½ΠΈΡΠΈ. Π¦Π΅Π»ΠΈΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½. Π’ΠΎΠ²Π° Π½Π°Π»Π°Π³Π° Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΈ ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ΡΠΎ Π½Π° ΠΎΡΠ΅ Π΅Π΄Π½ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΡ A.
ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π°, Π΅ ΠΊΡΠΈΡΠΈΡΠ½ΠΎ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΠ΄ ΠΏΠΎΠ΄ΠΏΠΈΡΠ° ΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π² ΠΏΡΠΎΡΠΈΠ²Π΅Π½ ΡΠ»ΡΡΠ°ΠΉ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π·Π°ΠΌΠ΅Π½ΠΈΠΌ IdXXX ΠΈ Π΄Π° ΠΏΠ΅ΡΠ΅ΠΏΠΎΠ΄ΠΏΠΈΡΠ΅ΠΌ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Ρ ΠΊΠ»ΡΡΠ° Π½Π° Π΄ΡΡΠ³ ΠΈΠ·Π²Π΅ΡΡΠ΅Π½ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ. ΠΠ° Π΄Π° ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΠΌ , Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΡΠ΅ ΡΠ²Π΅ΡΠΈΡΠ΅, ΡΠ΅ Π΅Π»Π΅ΠΌΠ΅Π½ΡΠΈΡΠ΅ ΠΏΠΎΠ΄ ΠΏΠΎΠ΄ΠΏΠΈΡΠ° ΡΠ° ΡΠ°Π·ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈ Π½Π° ΡΡΡΠΎΠ³ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ ΠΌΠ΅ΡΡΠ° ΡΠΏΠΎΡΠ΅Π΄ ΡΠ²ΠΎΡ ΡΠΌΠΈΡΡΠ»: Π°ΠΊΠΎ A ΠΏΠΎΠ΄ΠΏΠΈΡΠ²Π° (PubA, PubB), ΡΠΎ B ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠ²Π° (PubB, PubA). Π’ΠΎΠ²Π° ΡΡΡΠΎ ΠΏΠΎΠ΄ΡΠ΅ΡΡΠ°Π²Π° Π²Π°ΠΆΠ½ΠΎΡΡΡΠ° Π½Π° ΠΈΠ·Π±ΠΎΡΠ° Π½Π° ΡΡΡΡΠΊΡΡΡΠ° ΠΈ ΡΠΎΡΠΌΠ°Ρ Π½Π° ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈΡΠ΅ Π΄Π°Π½Π½ΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π°ΡΠ° Π² ASN.1 DER ΠΊΠΎΠ΄ΠΈΡΠ°Π½Π΅ ΡΠ΅ ΡΠΎΡΡΠΈΡΠ°Ρ: SET OF(PubA, PubB) ΡΠ΅ Π±ΡΠ΄Π΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎ Π½Π° SET OF(PubB, PubA).
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ ββββ¬βββ β IdA, PubA β βββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββ>β βSignPrvA, SignPubA = load()β β β βPrvA, PubA = DHgen() β β β βββββββββββββββββββββββββββββ βIdB, PubB, sign(SignPrvB, (IdB, PubA, PubB)) β βββββββββββββββββββββββββββββ β<βββββββββββββββββββββββββββββββββββββββββββββ βSignPrvB, SignPubB = load()β β β βPrvB, PubB = DHgen() β β β βββββββββββββββββββββββββββββ β sign(SignPrvA, (IdA, PubB, PubA)) β βββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββ>β βverify(SignPubB, ...)β β β βKey = DH(PrvA, PubB) β β β βββββββββββββββββββββββ β β
ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, Π²ΡΠ΅ ΠΎΡΠ΅ Π½Π΅ ΡΠΌΠ΅ Β«Π΄ΠΎΠΊΠ°Π·Π°Π»ΠΈΒ», ΡΠ΅ ΡΠΌΠ΅ ΠΏΡΠΎΠΈΠ·Π²Π΅Π»ΠΈ Π΅Π΄ΠΈΠ½ ΠΈ ΡΡΡΠΈ ΠΎΠ±Ρ ΠΊΠ»ΡΡ Π·Π° ΡΠ°Π·ΠΈ ΡΠ΅ΡΠΈΡ. Π ΠΏΡΠΈΠ½ΡΠΈΠΏΠ΅, ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΌΠΈΠ½Π΅ ΠΈ Π±Π΅Π· ΡΠ°Π·ΠΈ ΡΡΡΠΏΠΊΠ° β ΠΏΡΡΠ²ΠΎΡΠΎ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΡΠ΅ Π±ΡΠ΄Π΅ Π½Π΅Π²Π°Π»ΠΈΠ΄Π½ΠΎ, Π½ΠΎ ΠΈΡΠΊΠ°ΠΌΠ΅, ΠΊΠΎΠ³Π°ΡΠΎ ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅ΡΠΎ ΠΏΡΠΈΠΊΠ»ΡΡΠΈ, Π΄Π° ΡΠΌΠ΅ ΡΠ²Π΅ΡΠ΅Π½ΠΈ, ΡΠ΅ Π²ΡΠΈΡΠΊΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»Π½ΠΎ Π΅ ΡΡΠ³Π»Π°ΡΡΠ²Π°Π½ΠΎ. ΠΡΠΌ ΠΌΠΎΠΌΠ΅Π½ΡΠ° ΠΈΠΌΠ°ΠΌΠ΅ ISO/IEC IS 9798-3 ΠΏΡΠΎΡΠΎΠΊΠΎΠ».
ΠΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠ΅ΠΌ ΠΈ ΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΡ ΠΊΠ»ΡΡ. Π’ΠΎΠ²Π° Π΅ ΠΎΠΏΠ°ΡΠ½ΠΎ, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π½Π΅ Π΅ ΠΈΠ·ΠΊΠ»ΡΡΠ΅Π½ΠΎ Π² ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½ΠΈΡ Π°Π»Π³ΠΎΡΠΈΡΡΠΌ Π·Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠ²Π°Π½Π΅ Π΄Π° ΠΈΠΌΠ° ΠΈΠ·ΡΠΈΡΠ°Π½ΠΈΡ (Π΄ΠΎΡΠΈ ΠΈ Π±ΠΈΡΠΎΠ²Π΅ Π·Π° ΠΏΠΎΠ΄ΠΏΠΈΡ, Π½ΠΎ Π²ΡΠ΅ ΠΏΠ°ΠΊ ΠΈΠ·ΡΠΈΡΠ°Π½ΠΈΡ). ΠΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠ΅ΠΌ Ρ Π΅Ρ ΠΎΡ ΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΡ ΠΊΠ»ΡΡ, Π½ΠΎ ΠΈΠ·ΡΠΈΡΠ°Π½Π΅ΡΠΎ Π΄ΠΎΡΠΈ ΠΈ Π½Π° Ρ Π΅ΡΠ° ΠΎΡ ΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΡ ΠΊΠ»ΡΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° ΡΡΠΎΠΉΠ½ΠΎΡΡ ΠΏΡΠΈ brute-force Π°ΡΠ°ΠΊΠ° ΡΡΠ΅ΡΡ ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π·Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅. SIGMA ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° MAC ΡΡΠ½ΠΊΡΠΈΡ, Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠ°ΡΠ° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° Π½Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°ΡΠ°.
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ ββββ¬βββ β IdA, PubA β βββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββ>β βSignPrvA, SignPubA = load()β β β βPrvA, PubA = DHgen() β β β βββββββββββββββββββββββββββββ βIdB, PubB, sign(SignPrvB, (PubA, PubB)), MAC(IdB) β βββββββββββββββββββββββββββββ β<ββββββββββββββββββββββββββββββββββββββββββββββββββ βSignPrvB, SignPubB = load()β β β βPrvB, PubB = DHgen() β β β βββββββββββββββββββββββββββββ β β βββββββββββββββββββββββ β sign(SignPrvA, (PubB, PubA)), MAC(IdA) β βKey = DH(PrvA, PubB) β ββββββββββββββββββββββββββββββββββββββββββββββββββ>β βverify(Key, IdB) β β β βverify(SignPubB, ...)β β β βββββββββββββββββββββββ β β
ΠΠ°ΡΠΎ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ, Π½ΡΠΊΠΎΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΆΠ΅Π»Π°ΡΡ Π΄Π° ΠΏΡΠ΅ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ ΡΠ²ΠΎΠΈΡΠ΅ Π΅ΡΠ΅ΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅ (ΠΊΠΎΠ΅ΡΠΎ, ΡΠ°Π·Π±ΠΈΡΠ° ΡΠ΅, Π΅ ΠΆΠ°Π»ΠΊΠΎ Π·Π° PFS). ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π³Π΅Π½Π΅ΡΠΈΡΠ°Ρ ΠΌΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π° Π΄Π²ΠΎΠΉΠΊΠ°, ΠΎΠΏΠΈΡΠ°Ρ ΠΌΠ΅ ΡΠ΅ Π΄Π° ΡΠ΅ ΡΠ²ΡΡΠΆΠ΅ΠΌ, Π½ΠΎ TCP Π½Π΅ Π±Π΅ΡΠ΅ Π½Π°Π»ΠΈΡΠ΅Π½ ΠΈΠ»ΠΈ ΠΏΡΠ΅ΠΊΡΡΠ½Π°Ρ Π½ΡΠΊΡΠ΄Π΅ ΠΏΠΎ ΡΡΠ΅Π΄Π°ΡΠ° Π½Π° ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°. ΠΠ°Π»ΠΊΠΎ Π΅ Π΄Π° Ρ Π°ΡΡΠΈΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π°ΡΠ° Π΅Π½ΡΡΠΎΠΏΠΈΡ ΠΈ ΡΠ΅ΡΡΡΡΠΈ Π½Π° ΠΏΡΠΎΡΠ΅ΡΠΎΡΠ° Π·Π° Π½ΠΎΠ²Π° Π΄Π²ΠΎΠΉΠΊΠ°. ΠΠ°ΡΠΎΠ²Π° Π²ΡΠ²Π΅ΠΆΠ΄Π°ΠΌΠ΅ Ρ.Π½Π°Ρ. cookie β ΠΏΡΠ΅Π²Π΄ΠΎΡΠ»ΡΡΠ°ΠΉΠ½Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ, ΠΊΠΎΡΡΠΎ ΡΠ΅ Π·Π°ΡΠΈΡΠΈ ΠΎΡ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΈ ΡΠ»ΡΡΠ°ΠΉΠ½ΠΈ replay Π°ΡΠ°ΠΊΠΈ ΠΏΡΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Π΅ΡΠ΅ΡΠ½ΠΈΡΠ΅ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅. ΠΠΎΡΠ°Π΄ΠΈ ΡΠ²ΡΡΠ·Π°Π½ΠΎΡΡΡΠ° ΠΌΠ΅ΠΆΠ΄Ρ cookie ΠΈ Π΅ΡΠ΅ΡΠ½ΠΈΡ ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ΠΊΠ»ΡΡ, ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡΡ ΠΊΠ»ΡΡ Π½Π° ΠΏΡΠΎΡΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½Π°ΡΠ° ΡΡΡΠ°Π½Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΡΠ΅ΠΌΠ°Ρ Π½Π°Ρ ΠΎΡ ΠΏΠΎΠ΄ΠΏΠΈΡΠ° Π±Π΅Π· Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡ.
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ ββββ¬βββ β IdA, PubA, CookieA β βββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ>β βSignPrvA, SignPubA = load()β β β βPrvA, PubA = DHgen() β β β βββββββββββββββββββββββββββββ βIdB, PubB, CookieB, sign(SignPrvB, (CookieA, CookieB, PubB)), MAC(IdB) β βββββββββββββββββββββββββββββ ββ βverify(Key, IdB) β β β βverify(SignPubB, ...)β β β βββββββββββββββββββββββ β β
ΠΠ°ΠΊΡΠ°Ρ, ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° Π·Π°ΡΠΈΡΠΈΠΌ Π»ΠΈΡΠ½ΠΈΡΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΈ Π½Π° Π½Π°ΡΠΈΡΠ΅ ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΡΠΈ ΠΎΡ ΠΏΠ°ΡΠΈΠ²Π½ΠΈ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»ΠΈ. ΠΠ°ΡΠΎΠ²Π° SIGMA ΠΏΡΠ΅Π΄Π»Π°Π³Π° ΠΏΡΡΠ²ΠΎ Π΄Π° ΠΎΠ±ΠΌΠ΅Π½ΠΈΠΌ Π΅ΡΠ΅ΠΌΠ΅ΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅ ΠΈ Π΄Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ ΠΎΠ±Ρ ΠΊΠ»ΡΡ, Ρ ΠΊΠΎΠΉΡΠΎ Π΄Π° ΡΠΈΡΡΠΎΠ²Π°ΠΌΠ΅ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΎΠ½Π½ΠΈΡΠ΅ ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΡΠΈΡΠ°ΡΠΈΡΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ. SIGMA ΠΎΠΏΠΈΡΠ²Π° Π΄Π²Π° Π²Π°ΡΠΈΠ°Π½ΡΠ°:
- SIGMA-I β Π·Π°ΡΠΈΡΠ°Π²Π° ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ° ΠΎΡ Π°ΠΊΡΠΈΠ²Π½ΠΈ Π°ΡΠ°ΠΊΠΈ, Π° ΠΎΡΠ³ΠΎΠ²ΠΎΡΠ° ΠΎΡ ΠΏΠ°ΡΠΈΠ²Π½ΠΈ: ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΡΡ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠ° ΠΎΡΠ³ΠΎΠ²ΠΎΡΠ° ΠΈ, Π°ΠΊΠΎ Π½Π΅ΡΠΎ Π½Π΅ ΡΠ΅ ΡΡΠ²ΠΏΠ°Π΄Π°, Π½Π΅ ΡΠ°Π·ΠΊΡΠΈΠ²Π° ΡΠ²ΠΎΡΡΠ° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ. ΠΡΠ³ΠΎΠ²ΠΎΡΠ° ΠΎΠ±Π°ΡΠ΅ ΡΠ°Π·ΠΊΡΠΈΠ²Π° ΡΠ²ΠΎΡΡΠ° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ, Π°ΠΊΠΎ Π±ΡΠ΄Π΅ ΡΡΠ°ΡΡΠΈΡΠ°Π½ Π°ΠΊΡΠΈΠ²Π΅Π½ ΠΏΡΠΎΡΠΎΠΊΠΎΠ». ΠΠ°ΡΡΠΈΠ²Π΅Π½ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π» Π½Π΅ Π½Π°ΡΡΠ°Π²Π° Π°Π±ΡΠΎΠ»ΡΡΠ½ΠΎ Π½ΠΈΡΠΎ;
SIGMA-R β Π·Π°ΡΠΈΡΠ°Π²Π° ΠΎΡΠ³ΠΎΠ²ΠΎΡΠ° ΠΎΡ Π°ΠΊΡΠΈΠ²Π½ΠΈ Π°ΡΠ°ΠΊΠΈ, Π° ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ° ΠΎΡ ΠΏΠ°ΡΠΈΠ²Π½ΠΈ. ΠΡΠΈΡΠΊΠΎ Π΅ Π² ΡΠΎΡΠ½ΠΎΡΡ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ, Π½ΠΎ Π² ΡΠΎΠ·ΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Π²Π΅ΡΠ΅ ΡΠ΅ ΠΏΡΠ΅Π΄Π°Π²Π°Ρ ΡΠ΅ΡΠΈΡΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Π½Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅.ΠΠ·Π±ΠΈΡΠ°ΠΌΠ΅ SIGMA-I, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠΎΠΉ Π΅ ΠΏΠΎ-Π±Π»ΠΈΠ·ΡΠΊ Π΄ΠΎ ΠΎΠ½ΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ ΠΎΡΠ°ΠΊΠ²Π°ΠΌΠ΅ ΠΎΡ ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΠΈΡΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ-ΡΠ΅ΡΠ²Π΅ΡΠ½ΠΈ ΡΠ΅ΡΠ΅Π½ΠΈΡ: ΠΊΠ»ΠΈΠ΅Π½ΡΡΡ ΠΏΠΎΠ·Π½Π°Π²Π° ΡΠ°ΠΌΠΎ ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΠ΅Π½ΠΈΡ ΡΡΡΠ²ΡΡΠ°, Π° ΡΡΡΠ²ΡΡΡΡ Π·Π½Π°Π΅ Π²ΡΠΈΡΠΊΠΎ. ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π° Π΅ ΠΏΠΎ-Π»Π΅ΡΠ΅Π½ Π·Π° ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ ΠΏΠΎΡΠ°Π΄ΠΈ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΈΡ Π±ΡΠΎΠΉ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ Π·Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅. ΠΡΠΈΡΠΊΠΎ, ΠΊΠΎΠ΅ΡΠΎ Π΄ΠΎΠ±Π°Π²ΡΠΌΠ΅ Π² ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°, Π΅ ΡΠΈΡΡΠΎΠ²Π°Π½Π΅ Π½Π° ΡΠ°ΡΡ ΠΎΡ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΈ ΠΏΡΠ΅Ρ Π²ΡΡΠ»ΡΠ½Π΅ Π½Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° A Π² ΡΠΈΡΡΠΎΠ²Π°Π½Π°ΡΠ° ΡΠ°ΡΡ Π½Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΎΡΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅:
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ ββββ¬βββ β PubA, CookieA β βββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ>β βSignPrvA, SignPubA = load()β β β βPrvA, PubA = DHgen() β β β βββββββββββββββββββββββββββββ βPubB, CookieB, Enc((IdB, sign(SignPrvB, (CookieA, CookieB, PubB)), MAC(IdB))) β βββββββββββββββββββββββββββββ β<ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βSignPrvB, SignPubB = load()β β β βPrvB, PubB = DHgen() β β β βββββββββββββββββββββββββββββ β β βββββββββββββββββββββββ β Enc((IdA, sign(SignPrvA, (CookieB, CookieA, PubA)), MAC(IdA))) β βKey = DH(PrvA, PubB) β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ>β βverify(Key, IdB) β β β βverify(SignPubB, ...)β β β βββββββββββββββββββββββ β β
- ΠΠ° ΠΏΠΎΠ΄ΠΏΠΈΡΠ²Π°Π½Π΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΠΠ‘Π’ Π Π°Π»Π³ΠΎΡΠΈΡΡΠΌ Ρ 256-Π±ΠΈΡΠΎΠ²ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅.
- ΠΠ° Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΎΠ±ΡΠΈΡ ΠΊΠ»ΡΡ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° 34.10-2012 VKO.
- ΠΠ°ΡΠΎ MAC ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° CMAC. Π’Π΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈ ΡΠΎΠ²Π° Π΅ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅Π½ ΡΠ΅ΠΆΠΈΠΌ Π½Π° ΡΠ°Π±ΠΎΡΠ° Π½Π° Π±Π»ΠΎΡΠ΅Π½ ΡΠΈΡΡΡ, ΠΎΠΏΠΈΡΠ°Π½ Π² ΠΠΠ‘Π’ Π 34.13-2015. ΠΠ°ΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ Π·Π° ΡΠΈΡΡΠΎΠ²Π°Π½Π΅ Π·Π° ΡΠΎΠ·ΠΈ ΡΠ΅ΠΆΠΈΠΌ β (34.12-2015).
- ΠΠ°ΡΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ρ Π΅Ρ ΠΎΡ Π½Π΅Π³ΠΎΠ²ΠΈΡ ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ΠΊΠ»ΡΡ. ΠΠ° Ρ Π΅Ρ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° (34.11-2012 256 Π±ΠΈΡΠ°).
Π‘Π»Π΅Π΄ ΡΡΠΊΡΠ²Π°Π½Π΅ ΡΠ΅ ΠΈΠΌΠ°ΠΌΠ΅ ΡΡΠ³Π»Π°ΡΡΠ²Π°Π½ ΠΎΠ±Ρ ΠΊΠ»ΡΡ. ΠΠΎΠΆΠ΅ΠΌ Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π·Π° ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΠ΅Π½ΠΎ ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½Π΅ Π½Π° ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΠΈ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ. Π’Π°Π·ΠΈ ΡΠ°ΡΡ Π΅ Π½Π°ΠΏΡΠ»Π½ΠΎ ΠΏΡΠΎΡΡΠ° ΠΈ ΡΡΡΠ΄Π½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΡΠ±ΡΡΠΊΠ°: ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠΈΡΠ°ΠΌΠ΅ Π±ΡΠΎΡΡΠ° Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ°, ΠΊΡΠΈΠΏΡΠΈΡΠ°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ, ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ (MAC) Π±ΡΠΎΡΡΠ° ΠΈ ΡΠΈΡΡΠΎΠ²Π°Π½ ΡΠ΅ΠΊΡΡ, ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΌΠ΅. ΠΡΠΈ ΠΏΡΠΈΠ΅ΠΌΠ°Π½Π΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅, ΡΠ΅ Π±ΡΠΎΡΡΡΡ ΠΈΠΌΠ° ΠΎΡΠ°ΠΊΠ²Π°Π½Π°ΡΠ° ΡΡΠΎΠΉΠ½ΠΎΡΡ, ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ΅ΠΊΡΡ Ρ Π±ΡΠΎΡΡΠ°, Π΄Π΅ΠΊΡΠΈΠΏΡΠΈΡΠ°ΠΌΠ΅. Π‘ ΠΊΠΎΠΉ ΠΊΠ»ΡΡ Π΄Π° ΠΊΡΠΈΠΏΡΠΈΡΠ°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡΡΠ° Π·Π° ΡΡΠΊΡΠ²Π°Π½Π΅, ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΠΈΡΠ΅, Ρ ΠΊΠΎΠΉ Π΄Π° ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΠΈΠΌ? ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° Π΅Π΄ΠΈΠ½ ΠΊΠ»ΡΡ Π·Π° Π²ΡΠΈΡΠΊΠΈ ΡΠ΅Π·ΠΈ Π·Π°Π΄Π°ΡΠΈ Π΅ ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΈ Π½Π΅ΡΠ°Π·ΡΠΌΠ½ΠΎ. ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΅ Π΄Π° ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ°Ρ ΠΊΠ»ΡΡΠΎΠ²Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ (ΡΡΠ½ΠΊΡΠΈΡ Π·Π° ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡ). ΠΡΠ½ΠΎΠ²ΠΎ, Π½ΡΠΌΠ° Π΄Π° ΠΈΠ·ΠΌΠΈΡΠ»ΡΠΌΠ΅ Π½ΠΈΡΠΎ Π½ΠΎΠ²ΠΎ: ΠΎΡΠ΄Π°Π²Π½Π° Π΅ ΠΈΠ·Π²Π΅ΡΡΠ½Π°, Π΄ΠΎΠ±ΡΠ΅ ΠΏΡΠΎΡΡΠ΅Π½Π° ΠΈ Π½ΡΠΌΠ° ΠΈΠ·Π²Π΅ΡΡΠ½ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΈ. ΠΠ° ΡΡΠΆΠ°Π»Π΅Π½ΠΈΠ΅, Π² ΡΠΎΠ΄Π½Π°ΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π½Π° Python Π½ΡΠΌΠ° ΡΠ°Π·ΠΈ ΡΡΠ½ΠΊΡΠΈΡ, Π·Π°ΡΠΎΠ²Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ°. HKDF Π²Π»Π°Π³Π°ΡΠ΅ , ΠΊΠΎΠΉΡΠΎ ΠΎΡ ΡΠ²ΠΎΡ ΡΡΡΠ°Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ρ Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ. ΠΡΠΈΠΌΠ΅Ρ Π·Π° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π½Π° Python Π½Π° ΡΡΡΠ°Π½ΠΈΡΠ°ΡΠ° Wikipedia Π·Π°Π΅ΠΌΠ° ΡΡΠ²ΡΠ΅ΠΌ ΠΌΠ°Π»ΠΊΠΎ ΡΠ΅Π΄ΠΎΠ²Π΅ ΠΊΠΎΠ΄. ΠΠ°ΠΊΡΠΎ ΠΈ Π² ΡΠ»ΡΡΠ°Ρ Ρ 34.10-2012, ΠΊΠ°ΡΠΎ Ρ Π΅Ρ ΡΡΠ½ΠΊΡΠΈΡ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π‘ΡΡΠΈΠ±ΠΎΠ³-256. ΠΠ·Ρ ΠΎΠ΄ΡΡ ΠΎΡ Π½Π°ΡΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π·Π° ΡΡΠ³Π»Π°ΡΡΠ²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡΡΠΎΠ²Π΅ ΡΠ΅ Π±ΡΠ΄Π΅ Π½Π°ΡΠ΅ΡΠ΅Π½ ΡΠ΅ΡΠΈΠΎΠ½Π΅Π½ ΠΊΠ»ΡΡ, ΠΎΡ ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΡΠ΅ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ ΡΠΈΠΌΠ΅ΡΡΠΈΡΠ½ΠΈ:
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")Π‘ΡΡΡΠΊΡΡΡΠΈ/ΡΡ Π΅ΠΌΠΈ
ΠΠ΅ΠΊΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠ²ΠΈ ASN.1 ΡΡΡΡΠΊΡΡΡΠΈ ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅ Π·Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ ΡΠ΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ:
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 β ΡΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½ΠΎ (to be signed). HandshakeTBE β ΡΠΎΠ²Π°, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½ΠΎ (to be encrypted). ΠΠ±ΡΡΠ½Π΅ΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΏΠΎΠ»Π΅ΡΠΎ ukm Π² MsgHandshake1. 34.10 VKO, Π·Π° Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½Π° ΡΠ°Π½Π΄ΠΎΠΌΠΈΠ·Π°ΡΠΈΡ Π² Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½ΠΈΡΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π΅, Π²ΠΊΠ»ΡΡΠ²Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ UKM (user keying material) β ΠΏΡΠΎΡΡΠΎ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½Π° Π΅Π½ΡΡΠΎΠΏΠΈΡ.
ΠΠΎΠ±Π°Π²ΡΠ½Π΅ Π½Π° ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ Π² ΠΊΠΎΠ΄Π°
ΠΠ΅ΠΊΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡΠ°ΠΌΠΎ ΠΏΡΠΎΠΌΠ΅Π½ΠΈΡΠ΅ Π² ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½ΠΈΡ ΠΊΠΎΠ΄, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° ΠΎΡΡΠ°Π²Π° ΡΡΡΠ°ΡΠ° (Π²ΡΡΡΠ½ΠΎΡΡ, ΠΏΡΡΠ²ΠΎ Π±Π΅ΡΠ΅ Π½Π°ΠΏΠΈΡΠ°Π½Π° ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»Π½Π°ΡΠ° Π²Π΅ΡΡΠΈΡ, Π° ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° ΠΎΡ Π½Π΅Ρ ΡΠ΅ ΠΈΠ·ΡΡΠ·Π²Π°ΡΠ΅ ΡΡΠ»Π°ΡΠ° ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ).
Π’ΡΠΉ ΠΊΠ°ΡΠΎ Π°Π²ΡΠ΅Π½ΡΠΈΠΊΠ°ΡΠΈΡΡΠ° ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡΡΠ° Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΡΠΈΡΠ΅ ΡΠ΅ ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ²Π° ΡΡΠ΅Π· ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅, ΡΠ΅ ΡΠ΅Π³Π° ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΡΡΡ ΡΠ°Π½ΡΠ²Π°Ρ Π½ΡΠΊΡΠ΄Π΅ Π΄ΡΠ»Π³ΠΎΡΡΠΎΡΠ½ΠΎ. ΠΠ° ΠΏΡΠΎΡΡΠΎΡΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ JSON ΠΎΡ ΡΠ°ΠΊΡΠ² Π²ΠΈΠ΄:
{ "our": { "prv": "21254cf66c15e0226ef2669ceee46c87b575f37f9000272f408d0c9283355f98", "pub": "938c87da5c55b27b7f332d91b202dbef2540979d6ceaa4c35f1b5bfca6df47df0bdae0d3d82beac83cec3e353939489d9981b7eb7a3c58b71df2212d556312a1" }, "their": { "alice": "d361a59c25d2ca5a05d21f31168609deeec100570ac98f540416778c93b2c7402fd92640731a707ec67b5410a0feae5b78aeec93c4a455a17570a84f2bc21fce", "bob": "aade1207dd85ecd283272e7b69c078d5fae75b6e141f7649ad21962042d643512c28a2dbdc12c7ba40eb704af920919511180c18f4d17e07d7f5acd49787224a" } }our β Π½Π°ΡΠΈΡΡ ΠΊΠ»ΡΡΠΎΠ²ΠΈ Π΄Π²ΠΎΠΉΠΊΠ°, ΡΠ΅ΡΡΠ½Π°Π΄Π΅ΡΠ΅ΡΠΈΡΠ½ΠΈ ΡΠ°ΡΡΠ΅Π½ ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ΅Π½ ΠΊΠ»ΡΡ. their β ΠΈΠΌΠ΅Π½Π° Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΡΠΈΡΠ΅ ΠΈ ΡΠ΅Ρ Π½ΠΈΡΠ΅ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅. ΠΠ΅ΠΊΠ° ΠΏΡΠΎΠΌΠ΅Π½ΠΈΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΈΡΠ΅ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΈΡ ΡΠ΅Π΄ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΡΡΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° JSON Π΄Π°Π½Π½ΠΈΡΠ΅:
ΠΎΡ pygost import gost3410 ΠΎΡ 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="ΠΠ΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° JSON Ρ Π½ΠΎΠ²Π° Π΄Π²ΠΎΠΉΠΊΠ° ΠΊΠ»ΡΡΠΎΠ²Π΅", ) parser.add_argument( "--keys", default="keys.json", required=False, help="JSON Ρ Π½Π°ΡΠΈΡΠ΅ ΠΈ ΡΠ΅Ρ Π½ΠΈΡΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π΅", ) parser.add_argument( "--bind", default="::1", help="ΠΠ΄ΡΠ΅Ρ Π·Π° ΡΠ»ΡΡΠ°Π½Π΅", ) parser.add_argument( "--port", type=int, default=6666, help="ΠΠΎΡΡ Π·Π° ΡΠ»ΡΡΠ°Π½Π΅", ) 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) # ΠΠ°ΡΡΠ²Π°Π½Π΅ ΠΈ ΡΠ°Π·ΡΠΏΠ»ΡΡΠ½ΡΠ²Π°Π½Π΅ Π½Π° Π½Π°ΡΠΈΡΠ΅ ΠΈ ΡΠ΅Ρ Π½ΠΈΡΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π΅ {{{ 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), } # }}}ΠΡΠΈΠ²Π°ΡΠ½ΠΈΡΡ ΠΊΠ»ΡΡ Π½Π° Π°Π»Π³ΠΎΡΠΈΡΡΡΠ° 34.10 Π΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΎ ΡΠΈΡΠ»ΠΎ. Π‘ ΡΠ°Π·ΠΌΠ΅Ρ 256 Π±ΠΈΡΠ° Π·Π° 256-Π±ΠΈΡΠΎΠ²ΠΈ Π΅Π»ΠΈΠΏΡΠΈΡΠ½ΠΈ ΠΊΡΠΈΠ²ΠΈ. PyGOST ΡΠ°Π±ΠΎΡΠΈ Π½Π΅ Ρ Π½Π°Π±ΠΎΡ ΠΎΡ Π±Π°ΠΉΡΠΎΠ²Π΅, Π° Ρ , Π·Π°ΡΠΎΠ²Π° Π½Π°ΡΠΈΡΡ ΠΏΡΠΈΠ²Π°ΡΠ΅Π½ ΠΊΠ»ΡΡ (urandom(32)) ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠΈΡΠ°Π½ Π² ΡΠΈΡΠ»ΠΎ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ gost3410.prv_unmarshal(). ΠΡΠ±Π»ΠΈΡΠ½ΠΈΡΡ ΠΊΠ»ΡΡ ΡΠ΅ ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π° Π΄Π΅ΡΠ΅ΡΠΌΠΈΠ½ΠΈΡΠ°Π½ΠΎ ΠΎΡ ΠΏΡΠΈΠ²Π°ΡΠ½ΠΈΡ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ gost3410.public_key(). ΠΡΠ±Π»ΠΈΡΠ½ΠΈΡΡ ΠΊΠ»ΡΡ 34.10 ΡΠ΅ ΡΡΡΡΠΎΠΈ ΠΎΡ Π΄Π²Π΅ Π³ΠΎΠ»Π΅ΠΌΠΈ ΡΠΈΡΠ»Π°, ΠΊΠΎΠΈΡΠΎ ΡΡΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π°Ρ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ²Π°Π½ΠΈ Π² Π±Π°ΠΉΡΠΎΠ²Π° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡ Π·Π° ΡΠ΄ΠΎΠ±ΡΡΠ²ΠΎ ΠΏΡΠΈ ΡΡΡ ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ gost3410.pub_marshal().
Π‘Π»Π΅Π΄ ΠΏΡΠΎΡΠΈΡΠ°Π½Π΅ Π½Π° JSON ΡΠ°ΠΉΠ»Π°, ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π΅ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ²Π°Ρ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ gost3410.pub_unmarshal(). Π’ΡΠΉ ΠΊΠ°ΡΠΎ ΡΠ΅ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΈ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° ΠΏΠΎΠ΄ ΡΠΎΡΠΌΠ°ΡΠ° Π½Π° Ρ Π΅Ρ ΠΎΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡ ΠΊΠ»ΡΡ, ΡΠ΅ ΠΌΠΎΠ³Π°Ρ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»Π½ΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·ΡΠΈΡΠ»ΡΡ ΠΈ ΠΏΠΎΡΡΠ°Π²ΡΡ Π² ΡΠ΅ΡΠ½ΠΈΠΊ Π·Π° Π±ΡΡΠ·ΠΎ ΡΡΡΡΠ΅Π½Π΅. Π‘ΡΡΠΈΠ±ΠΎΠ³-256 Ρ Π΅ΡΡΡ Π΅ gost34112012256.GOST34112012256(), ΠΈΠ·ΡΡΠ»ΠΎ ΡΠ΄ΠΎΠ²Π»Π΅ΡΠ²ΠΎΡΡΠ²Π°Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π½Π° hashlib Π·Π° Ρ Π΅Ρ ΡΡΠ½ΠΊΡΠΈΠΈ.
ΠΠ°ΠΊ ΡΠ΅ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ ΠΊΠΎΡΡΡΠΈΠ½Π°ΡΠ° Π½Π° ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ°? ΠΡΠΈΡΠΊΠΎ Π΅ ΠΏΠΎ ΡΡ Π΅ΠΌΠ°ΡΠ° Π½Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅ΡΠΎ: Π³Π΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ° (128 Π±ΠΈΡΠ° ΡΠ° Π½Π°ΠΏΡΠ»Π½ΠΎ Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΈ), Π΅ΡΠΈΠΌΠ΅ΡΠ΅Π½ ΠΊΠ»ΡΡΠΎΠ² Π½Π°Π±ΠΎΡ 34.10, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° 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 # ΠΠ΅Π½Π΅ΡΠΈΡΠ°ΠΌΠ΅ Π½Π°ΡΠ΅ΡΠΎ Π΅ΠΏhemeral ΠΏΡΠ±Π»ΠΈΡΠ½ΠΎ ΠΊΠ»ΡΡ ΠΈ Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠ°, ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Handshake 0 {{{ 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()- ΠΎΡΠ°ΠΊΠ²Π°ΠΌΠ΅ ΠΎΡΠ³ΠΎΠ²ΠΎΡ ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°ΠΌΠ΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎΡΠΎ Msg ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅;
- ΡΠ±Π΅ΠΆΠ΄Π°Π²Π°ΠΌΠ΅ ΡΠ΅, ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡ ΠΌΠ΅ handshake1;
- Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ°ΠΌΠ΅ Π΅ΠΏhemeral ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡ ΠΊΠ»ΡΡ Π½Π° ΠΏΡΠΎΡΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½Π°ΡΠ° ΡΡΡΠ°Π½Π° ΠΈ ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π°ΠΌΠ΅ ΡΠ΅ΡΠΈΠΎΠ½Π½ΠΈΡ ΠΊΠ»ΡΡ;
- ΡΡΠ·Π΄Π°Π²Π°ΠΌΠ΅ ΡΠΈΠΌΠ΅ΡΡΠΈΡΠ½ΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π½Π° TBE ΡΠ°ΡΡΡΠ° ΠΎΡ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ.
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 # ΠΠ°Π»ΠΈΠ΄ΠΈΡΠ°ΠΌΠ΅ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Π·Π° Handshake {{{ 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 Π΅ 64-Π±ΠΈΡΠΎΠ² Π½ΠΎΠΌΠ΅Ρ (urandom(8)), ΠΊΠΎΠΉΡΠΎ ΡΡΡΠΎ ΠΈΠ·ΠΈΡΠΊΠ²Π° Π΄Π΅ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡ Π±Π°ΠΉΡΠΎΠ²ΠΎΡΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΡΠ½Π΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ gost3410_vko.ukm_unmarshal(). VKO ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π·Π° 34.10-2012 256-Π±ΠΈΡΠΎΠ²Π° Π΅ gost3410_vko.kek_34102012256() (KEK β ΠΊΠ»ΡΡ Π·Π° ΠΊΡΠΈΠΏΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΊΠ»ΡΡ).
ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΡΡ ΡΠ΅ΡΠΈΠΎΠ½Π΅Π½ ΠΊΠ»ΡΡ Π²Π΅ΡΠ΅ Π΅ 256-Π±ΠΈΡΠΎΠ²Π° Π±Π°ΠΉΡΠΎΠ²Π° ΠΏΡΠ΅Π²Π΄ΠΎΡΠ»ΡΡΠ°ΠΉΠ½Π° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡ. Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ, ΡΠΎΠΉ Π²Π΅Π΄Π½Π°Π³Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² HKDF ΡΡΠ½ΠΊΡΠΈΡΡΠ°. Π’ΡΠΉ ΠΊΠ°ΡΠΎ GOST34112012256 ΠΎΡΠ³ΠΎΠ²Π°ΡΡ Π½Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Π½Π° hashlib, ΡΠΎΠΉ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π΄ΠΈΡΠ΅ΠΊΡΠ½ΠΎ Π² ΠΊΠ»Π°ΡΠ° Hkdf. Π‘ΠΎΠ»ΡΠ° (ΠΏΡΡΠ²ΠΈΡΡ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ Π½Π° Hkdf) Π½Π΅ Ρ ΡΠΊΠ°Π·Π²Π°ΠΌΠ΅, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡΠ΅ ΠΊΠ»ΡΡΠΎΠ²Π΅ ΠΏΠΎΡΠ°Π΄ΠΈ Π΅ΠΏhemeralΠ½ΠΎΡΡΡΠ° Π½Π° ΡΡΠ°ΡΡΠΈΠ΅ Π½Π° ΠΊΠ»ΡΡΠΎΠ²ΠΈΡΠ΅ Π΄Π²ΠΎΠΉΠΊΠΈ ΡΠ΅ Π±ΡΠ΄Π°Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π·Π° Π²ΡΡΠΊΠ° ΡΠ΅ΡΠΈΡ ΠΈ Π² Π½Π΅Π³ΠΎ Π²Π΅ΡΠ΅ ΠΈΠΌΠ° Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π΅Π½ΡΡΠΎΠΏΠΈΡ. kdf.expand() ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ Π²Π΅ΡΠ΅ Π²ΡΡΡΠ° ΠΊΠ»ΡΡΠΎΠ²Π΅ Ρ Π΄ΡΠ»ΠΆΠΈΠ½Π° 256 Π±ΠΈΡΠ°, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° ΠΡΠ·Π½Π΅ΡΠΈΠΊΠ° Π² ΠΏΠΎ-ΠΊΡΡΠ΅Π½ Π΅ΡΠ°ΠΏ.
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°Ρ TBE ΠΈ TBS ΡΠ°ΡΡΠΈΡΠ΅ Π½Π° ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎΡΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅:
- ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π° ΡΠ΅ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° MAC Π½Π°Π΄ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎΡΠΎ ΡΠΈΡΡΠΎΠ²Π°Π½ ΡΠ΅ΠΊΡΡ;
- Π΄Π΅ΡΠΈΡΡΠΈΡΠ° ΡΠ΅ ΡΠΈΡΡΠΎΠ²Π°Π½ ΡΠ΅ΠΊΡΡ;
- Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ° ΡΠ΅ TBE ΡΡΡΡΠΊΡΡΡΠ°;
- ΠΎΡ Π½Π΅Ρ ΡΠ΅ Π²Π·ΠΈΠΌΠ° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡΡ Π½Π° ΠΎΠΏΠΎΠ½Π΅Π½ΡΠ° ΠΈ ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° Π΄Π°Π»ΠΈ Π½ΠΈ Π΅ ΠΈΠ·Π²Π΅ΡΡΠ΅Π½;
- ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π° ΡΠ΅ ΠΈ ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° MAC Π½Π°Π΄ ΡΠΎΠ·ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ;
- ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° ΡΠ΅ ΠΏΠΎΠ΄ΠΏΠΈΡΡΡ Π½Π°Π΄ TBS ΡΡΡΡΠΊΡΡΡΠ°ΡΠ°, Π² ΠΊΠΎΡΡΠΎ Π²Π»ΠΈΠ·Π°Ρ Π±ΠΈΡΠΊΠ²ΠΈΡΠΊΠΈΡΠ΅ Π½Π° Π΄Π²Π΅ΡΠ΅ ΡΡΡΠ°Π½ΠΈ ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡΡ Π΅ΡΠΈΠΌΠ΅ΡΠ΅Π½ ΠΊΠ»ΡΡ Π½Π° ΠΏΡΠΎΡΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½Π°ΡΠ° ΡΡΡΠ°Π½Π°. ΠΠΎΠ΄ΠΏΠΈΡΡΡ ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° Π΄ΡΠ»Π³ΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΊΠ»ΡΡ Π·Π° ΠΏΠΎΠ΄ΠΏΠΈΡ Π½Π° ΡΡΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°.
441 ΠΎΠΏΠΈΡ: 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 ΠΎΡΠ²Π΅Π½ Π°ΠΊΠΎ ValueError ΠΊΠ°ΡΠΎ Π³ΡΠ΅ΡΠΊΠ°: 452 logging.warning("%s: %s, ΠΏΡΠ΅ΠΊΡΡΠ²Π°Π½Π΅ Π½Π° Π²ΡΡΠ·ΠΊΠ°ΡΠ°", _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("Π½Π΅Π²Π°Π»ΠΈΠ΄Π΅Π½ 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 ΠΎΡΠ²Π΅Π½ Π°ΠΊΠΎ ASN1Error: 150 raise ValueError("Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠ° 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("Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎΡΡ") 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("Π½Π΅Π²Π°Π»ΠΈΠ΄Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎΡΡ 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("Π½Π΅Π²Π°Π»ΠΈΠ΄Π΅Π½ ΠΏΠΎΠ΄ΠΏΠΈΡ") 174 return peer["name"]ΠΠ°ΠΊΡΠΎ Π²Π΅ΡΠ΅ ΡΠΏΠΎΠΌΠ΅Π½Π°Ρ , 34.13-2015 ΠΎΠΏΠΈΡΠ²Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΎΡ 34.12-2015. Π‘ΡΠ΅Π΄ ΡΡΡ ΠΈΠΌΠ° ΡΠ΅ΠΆΠΈΠΌ Π·Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΈΠΌΠΈΡΠΎΠ²ΡΡΠ°Π²ΠΊΠΈ, ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π°Π½Π΅ Π½Π° MAC. Π PyGOST ΡΠΎΠ²Π° Π΅ gost3413.mac(). Π’ΠΎΠ·ΠΈ ΡΠ΅ΠΆΠΈΠΌ ΠΈΠ·ΠΈΡΠΊΠ²Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΡΠ½ΠΊΡΠΈΡ Π·Π° ΡΠΈΡΡΠΈΡΠ°Π½Π΅ (ΠΏΡΠΈΠ΅ΠΌΠ°ΡΠ° ΠΈ Π²ΡΡΡΠ°ΡΠ° Π΅Π΄ΠΈΠ½ Π±Π»ΠΎΠΊ Π΄Π°Π½Π½ΠΈ), ΡΠ°Π·ΠΌΠ΅ΡΠ° Π½Π° ΡΠΈΡΡΠΎΠ±Π»ΠΎΠΊΠ° ΠΈ ΡΠ°ΠΌΠΈΡΠ΅ Π΄Π°Π½Π½ΠΈ. ΠΠ°ΡΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π·Π°Π΄Π°Π΄Π΅ ΡΠ°Π·ΠΌΠ΅ΡΡΡ Π½Π° ΡΠΈΡΡΠΎΠ±Π»ΠΎΠΊΠ° Π½Π° ΡΠ²ΡΡΠ΄ΠΎ? 34.12-2015 ΠΎΠΏΠΈΡΠ²Π° Π½Π΅ ΡΠ°ΠΌΠΎ 128-Π±ΠΈΡΠΎΠ²ΠΈΡ ΡΠΈΡΡΡ ΠΡΠ·Π½Π΅ΡΠΈΠΊ, Π½ΠΎ ΠΈ 64-Π±ΠΈΡΠΎΠ²ΠΈΡ β ΠΌΠ°Π»ΠΊΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ ΠΠΠ‘Π’ 28147-89, ΡΡΠ·Π΄Π°Π΄Π΅Π½ ΠΎΡΠ΅ Π² ΠΠΠ ΠΈ Π²ΡΠ΅ ΠΎΡΠ΅ ΠΏΡΠΈΡΠ΅ΠΆΠ°Π²Π°Ρ Π΅Π΄ΠΈΠ½ ΠΎΡ Π½Π°ΠΉ-Π²ΠΈΡΠΎΠΊΠΈΡΠ΅ ΠΏΡΠ°Π³ΠΎΠ²Π΅ Π½Π° ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ.
ΠΡΠ·Π½Π΅ΡΠΈΠΊ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠ° gost.3412.GOST3412Kuznechik(key) ΠΈΠ·Π²ΠΈΠΊΠ²Π° ΠΈ Π²ΡΡΡΠ° ΠΎΠ±Π΅ΠΊΡ Ρ ΠΌΠ΅ΡΠΎΠ΄ΠΈΡΠ΅ .encrypt()/ .decrypt(), ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈ Π·Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ Π² 34.13 ΡΡΠ½ΠΊΡΠΈΠΈ. MAC ΡΠ΅ ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π° ΠΏΠΎ ΡΠ»Π΅Π΄Π½ΠΈΡ Π½Π°ΡΠΈΠ½: gost3413.mac(GOST3412Kuznechik(key).encrypt, KUZNECHIK_BLOCKSIZE, ciphertext). ΠΠ° ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Π½Π° ΠΈΠ·ΡΠΈΡΠ»Π΅Π½ΠΈΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ MAC Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ (==) Π½Π° Π±Π°ΠΉΡΠΎΠ²ΠΈ Π½ΠΈΠ·ΠΎΠ²Π΅, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠ°Π·ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π΄Π°Π²Π° ΠΈΠ·ΡΠΈΡΠ°Π½Π΅ Π½Π° Π²ΡΠ΅ΠΌΠ΅ΡΠΎ Π·Π° ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ, Π² ΠΎΠ±ΡΠΈΡ ΡΠ»ΡΡΠ°ΠΉ, ΠΌΠΎΠΆΠ΅ Π΄Π° Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ ΡΠ°ΡΠ°Π»Π½ΠΈ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠΈ ΠΎΡ ΡΠΈΠΏΠ° Π°ΡΠ°ΠΊΠΈΡΠ΅ ΡΡΠ΅ΡΡ TLS. Π Python ΠΈΠΌΠ° ΡΠΏΠ΅ΡΠΈΠ°Π»Π½Π° ΡΡΠ½ΠΊΡΠΈΡ hmac.compare_digest Π·Π° ΡΠΎΠ²Π°.
Π€ΡΠ½ΠΊΡΠΈΡΡΠ° Π·Π° Π±Π»ΠΎΡΠ½ΠΎ ΡΠΈΡΡΠΈΡΠ°Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠΈΡΡΠΎΠ²Π° ΡΠ°ΠΌΠΎ Π΅Π΄ΠΈΠ½ Π±Π»ΠΎΠΊ ΠΎΡ Π΄Π°Π½Π½ΠΈ. ΠΠ° ΠΏΠΎ-Π³ΠΎΠ»ΡΠΌΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ, ΠΈ ΠΎΡΠΎΠ±Π΅Π½ΠΎ Ρ Π½Π΅ ΠΊΡΠ°ΡΠ½Π° Π΄ΡΠ»ΠΆΠΈΠ½Π°, Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΠ΅ΠΆΠΈΠΌ Π½Π° ΡΠΈΡΡΠΈΡΠ°Π½Π΅. Π 34.13-2015 ΡΠ° ΠΎΠΏΠΈΡΠ°Π½ΠΈ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅: ECB, CTR, OFB, CBC, CFB. ΠΡΠ΅ΠΊΠΈ ΠΈΠΌΠ° ΡΠ²ΠΎΠΈ Π΄ΠΎΠΏΡΡΡΠΈΠΌΠΈ ΡΡΠ΅ΡΠΈ Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Ρ Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ. ΠΠ° Π³ΠΎΠ»ΡΠΌΠΎ ΡΡΠΆΠ°Π»Π΅Π½ΠΈΠ΅, Π²ΡΠ΅ ΠΎΡΠ΅ Π½ΡΠΌΠ°ΠΌΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΠΈΠ·ΠΈΡΠ°Π½ΠΈ (ΠΊΠ°ΡΠΎ CCM, OCB, GCM ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ) β ΠΏΡΠΈΠ½ΡΠ΄ΠΈΡΠ΅Π»Π½ΠΎ ΡΠΌΠ΅ ΠΎΠ±ΡΠ΅ΠΌΠ΅Π½Π΅Π½ΠΈ ΠΏΠΎΠ½Π΅ Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ MAC. ΠΠ·Π±ΡΠ°Ρ (CTR): ΡΠΎΠΉ Π½Π΅ ΠΈΠ·ΠΈΡΠΊΠ²Π° Π΄ΠΎΠΏΡΠ»Π½Π΅Π½ΠΈΡ Π΄ΠΎ ΡΠ°Π·ΠΌΠ΅ΡΠ° Π½Π° Π±Π»ΠΎΠΊΠ°, ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΠ°ΡΠ°Π»Π΅Π»ΠΈΠ·ΠΈΡΠ°Π½, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΠ°ΠΌΠΎ ΡΡΠ½ΠΊΡΠΈΡ Π·Π° ΡΠΈΡΡΠΈΡΠ°Π½Π΅ ΠΈ ΠΌΠΎΠΆΠ΅ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΡΠΈΡΡΠΈΡΠ°Π½Π΅ Π½Π° Π³ΠΎΠ»ΡΠΌΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ (Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ CBC, ΠΏΡΠΈ ΠΊΠΎΠΉΡΠΎ ΡΡΠ°Π²Π½ΠΈΡΠ΅Π»Π½ΠΎ Π±ΡΡΠ·ΠΎ Π·Π°ΠΏΠΎΡΠ²Π°Ρ ΠΊΠΎΠ»ΠΈΠ·ΠΈΠΈΡΠ΅).
ΠΠ°ΠΊΡΠΎ .mac(), .ctr() ΠΏΡΠΈΠ΅ΠΌΠ° ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ Π΄Π°Π½Π½ΠΈ Π½Π° Π²Ρ ΠΎΠ΄Π°: ciphertext = gost3413.ctr(GOST3412Kuznechik(key).encrypt, KUZNECHIK_BLOCKSIZE, plaintext, iv). ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΅ Π·Π°Π΄Π°Π²Π°Π½Π΅ Π½Π° Π²Π΅ΠΊΡΠΎΡ Π·Π° ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ, Ρ Π΄ΡΠ»ΠΆΠΈΠ½Π° ΡΠΎΡΠ½ΠΎ Π² ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π°ΡΠ° Π½Π° ΡΠΈΡΡΠΎΠ±Π»ΠΎΠΊΠ°. ΠΠΊΠΎ Π½Π°ΡΠΈΡΡ ΡΠΈΡΡΠΎΠ² ΠΊΠ»ΡΡ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΠ°ΠΌΠΎ Π·Π° ΡΠΈΡΡΠΎΠ²Π°Π½Π΅ Π½Π° Π΅Π΄Π½ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ (Π΄ΠΎΡΠΈ ΠΈ ΠΎΡ Π½ΡΠΊΠΎΠ»ΠΊΠΎ Π±Π»ΠΎΠΊΠ°), Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ΅ Π·Π°Π΄Π°Π΄Π΅ Π½ΡΠ»Π΅Π² Π²Π΅ΠΊΡΠΎΡ Π·Π° ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ. ΠΠ° ΡΠΈΡΡΠΎΠ²Π°Π½Π΅ Π½Π° handshake ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π²ΡΠ΅ΠΊΠΈ ΠΏΡΡ ΠΎΡΠ΄Π΅Π»Π΅Π½ ΠΊΠ»ΡΡ.
ΠΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ° Π½Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠ° gost3410.verify() Π΅ ΡΡΠΈΠ²ΠΈΠ°Π»Π½Π°: ΠΏΡΠ΅Π΄Π°Π²Π°ΠΌΠ΅ Π΅Π»ΠΈΠΏΡΠΈΡΠ½Π°ΡΠ° ΠΊΡΠΈΠ²Π°, Π² ΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΠ΅ Π½Π° ΠΊΠΎΡΡΠΎ ΡΠ°Π±ΠΎΡΠΈΠΌ (ΠΊΠΎΡΡΠΎ ΠΏΡΠΎΡΡΠΎ ΡΠΈΠΊΡΠΈΡΠ°ΠΌΠ΅ Π² Π½Π°ΡΠΈΡ GOSTIM ΠΏΡΠΎΡΠΎΠΊΠΎΠ»), ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈΡ ΠΊΠ»ΡΡ Π½Π° ΠΏΠΎΠ΄ΠΏΠΈΡΠ²Π°ΡΠΈΡ (Π½Π΅ Π·Π°Π±ΡΠ°Π²ΡΠΉΡΠ΅, ΡΠ΅ ΡΠΎΠ²Π° ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΊΠΎΡΡΠ΅ΠΆ ΠΎΡ Π΄Π²Π΅ Π³ΠΎΠ»Π΅ΠΌΠΈ ΡΠΈΡΠ»Π°, Π° Π½Π΅ Π±Π°ΠΉΡΠΎΠ² Π½ΠΈΠ·), 34.11-2012 Ρ Π΅Ρ ΠΈ ΡΠ°ΠΌΠΈΡ ΠΏΠΎΠ»ΡΡΠ΅Π½ ΠΏΠΎΠ΄ΠΏΠΈΡ.
Π‘Π»Π΅Π΄ ΡΠΎΠ²Π°, Π² ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ° ΠΏΠΎΠ΄Π³ΠΎΡΠ²ΡΠΌΠ΅ ΠΈ ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΌΠ΅ handshake2 ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Π·Π° ΡΡΠΊΠΎΡΡΠΈΡΠΊΠ°Π½Π΅, ΠΈΠ·Π²ΡΡΡΠ²Π°ΠΉΠΊΠΈ ΡΡΡΠΈΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΠΊΠΎΠΈΡΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡ ΠΌΠ΅ ΠΏΡΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ°, ΡΠ°ΠΌΠΎ ΡΠΈΠΌΠ΅ΡΡΠΈΡΠ½ΠΎ: ΠΏΠΎΠ΄ΠΏΠΈΡ Π²ΡΡΡ Ρ ΡΠΎΠ±ΡΡΠ²Π΅Π½ΠΈΡΠ΅ ΡΠΈ ΠΊΠ»ΡΡΠΎΠ²Π΅ Π²ΠΌΠ΅ΡΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΈ Ρ.Π½...
456 # ΠΠΎΠ΄Π³ΠΎΡΠΎΠ²ΡΡΠ΅ ΠΈ ΠΎΡΠΏΡΠ°Π²ΡΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Handshake 2 {{{ 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: ΡΠ΅ΡΡΠΈΡ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π°: %s", _id, peer_name)ΠΠΎΠ³Π΄Π° ΡΠ΅ΡΡΠΈΡ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π°, Π³Π΅Π½Π΅ΡΠΈΡΡΡΡΡΡ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΠ΅ ΠΊΠ»ΡΡΠΈ (ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΊΠ»ΡΡ Π΄Π»Ρ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ, Π΄Π»Ρ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ, Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· ΡΡΠΎΡΠΎΠ½), ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΡΡΡ ΠΡΠ·Π½Π΅ΡΠΈΠΊ Π΄Π»Ρ Π΄Π΅ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ MAC:
499 # ΠΠ°ΠΏΡΡΡΠΈΡΠ΅ ΠΎΡΠΏΡΠ°Π²ΠΈΡΠ΅Π»Ρ ΡΠ΅ΠΊΡΡΠΎΠ²ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠΉΡΠ΅ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ° {{{ 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 # ΠΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΡΠ΅ΡΡΠΎΠ²ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ {{{ 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 ΠΊΠΎΡΡΡΠΈΠ½Π° ΡΠ΅ΠΏΠ΅ΡΡ ΡΠΈΡΡΡΠ΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅Π΄ ΠΎΡΠΏΡΠ°Π²ΠΊΠΎΠΉ Π² TCP-ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅. Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΌΠΎΠ½ΠΎΡΠΎΠ½Π½ΠΎ Π²ΠΎΠ·ΡΠ°ΡΡΠ°ΡΡΠΈΠΉ nonce, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ°ΠΊΠΆΠ΅ ΡΠ²Π»ΡΠ΅ΡΡΡ Π²Π΅ΠΊΡΠΎΡΠΎΠΌ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΈ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΠΈ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΡΡΡΡΠΈΠΊΠ°. Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΈ Π±Π»ΠΎΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎ Π±ΡΠ΄ΡΡ ΠΎΡΠ»ΠΈΡΠ°ΡΡΠΈΠ΅ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΡΡΡΡΠΈΠΊΠ°.
Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ 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 += 1ΠΡ ΠΎΠ΄ΡΡΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ ΠΊΠΎΡΡΡΠΈΠ½ΠΎΠΉ msg_receiver, Π·Π°Π½ΠΈΠΌΠ°ΡΡΠ΅ΠΉΡΡ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠ΅ΠΉ ΠΈ Π΄Π΅ΡΠΈΡΡΠ°ΡΠΈΠ΅ΠΉ:
Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ 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("Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ nonce") mac_tag = mac(macer, KUZNECHIK_BLOCKSIZE, payload.encode()) if not compare_digest(mac_tag, bytes(msg_text["payloadMac"])): raise ValueError("Π½Π΅Π΄ΠΎΠΏΡΡΡΠΈΠΌΡΠΉ 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)ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
GOSTIM ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π² ΡΡΠ΅Π±Π½ΡΡ ΡΠ΅Π»ΡΡ (ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π½Π΅ ΠΏΠΎΠΊΡΡΡ ΡΠ΅ΡΡΠ°ΠΌΠΈ, ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ)! ΠΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°ΡΠ°ΡΡ (Π‘ΡΡΠΈΠ±ΠΎΠ³-256 Ρ ΡΡ: 995bbd368c04e50a481d138c5fa2e43ec7c89bc77743ba8dbabee1fde45de120). ΠΠ°ΠΊ ΠΈ Π²ΡΠ΅ ΠΌΠΎΠΈ ΠΏΡΠΎΠ΅ΠΊΡΡ, ΡΠΈΠΏΠ° , , , , GOSTIM ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ , ΡΠ°Π·ΠΏΡΠΎΡΡΡΠ°Π½ΡΠ²Π°Π½ ΠΏΡΠΈ ΡΡΠ»ΠΎΠ²ΠΈΡΡΠ° Π½Π° .
, , ΡΠ»Π΅Π½ , Python/Go-ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ, Π³Π»Π°Π²Π΅Π½ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΡΡ .
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
