ΠΡΠ΄ΡΡΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠΌ
ΠΡΡ ΡΡΠΎ ΠΏΠΎΠ±ΡΠ΄ΠΈΠ»ΠΎ ΠΌΠ΅Π½Ρ Π½Π°ΠΏΠΈΡΠ°ΡΡ Π΄Π°Π½Π½ΡΡ ΡΡΠ°ΡΡΡ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ, ΡΡΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΎΠ² ΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΠ³ΠΎ IM-Π° Π½Π΅ ΡΠ°ΠΊΠ°Ρ ΡΠ»ΠΎΠΆΠ½Π°Ρ Π·Π°Π΄Π°ΡΠ°. ΠΠ΄Π½Π°ΠΊΠΎ, ΠΈΠ·ΠΎΠ±ΡΠ΅ΡΠ°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Ρ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΈ ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ»ΡΡΠ΅ΠΉ Π½Π΅ ΡΡΠΎΠΈΡ.
Π ΡΡΠ°ΡΡΠ΅ Π±ΡΠ΄Π΅Ρ Π½Π°ΠΏΠΈΡΠ°Π½
ΠΠΈΠ·Π°ΠΉΠ½ IM
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π°, Π½Π°Π΄ΠΎ ΠΏΠΎΠ½ΡΡΡ ΠΊΠ°ΠΊ Π±ΡΠ΄Π΅Ρ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ Π½Π°Ρ IM. ΠΠ»Ρ ΠΏΡΠΎΡΡΠΎΡΡ, ΠΏΡΡΠΊΠ°ΠΉ ΡΡΠΎ Π±ΡΠ΄Π΅Ρ peer-to-peer ΡΠ΅ΡΡ, Π±Π΅Π· ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΡΡΠ°ΡΡΠ½ΠΈΠΊΠΎΠ². Π‘ΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΡΡΡΠ½ΠΎ Π±ΡΠ΄Π΅ΠΌ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΊ ΠΊΠ°ΠΊΠΎΠΌΡ Π°Π΄ΡΠ΅ΡΡ: ΠΏΠΎΡΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡΡΡ Π΄Π»Ρ ΠΎΠ±ΡΠ΅Π½ΠΈΡ Ρ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠΎΠΌ.
Π― ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ, ΡΡΠΎ, Π½Π° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ, ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎ Π΄ΠΎΡΡΡΠΏΠ½ΠΎΡΡΠΈ ΠΏΡΡΠΌΠΎΠΉ ΡΠ²ΡΠ·ΠΈ ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΠΌΠΈ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠ°ΠΌΠΈ β ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΠΌΠΎΡΡΠΈ IM Π½Π° ΠΏΡΠ°ΠΊΡΠΈΠΊΠ΅. ΠΠΎ ΡΠ΅ΠΌ Π±ΠΎΠ»ΡΡΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π±ΡΠ΄ΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²ΡΠ²Π°ΡΡ Π²ΡΡΠΊΠΈΠ΅ NAT-traversal ΠΊΠΎΡΡΡΠ»ΠΈ, ΡΠ΅ΠΌ Π΄ΠΎΠ»ΡΡΠ΅ ΠΌΡ ΡΠ°ΠΊ ΠΈ Π±ΡΠ΄Π΅ΠΌ ΠΎΡΡΠ°Π²Π°ΡΡΡΡ Π² IPv4 ΠΠ½ΡΠ΅ΡΠ½Π΅ΡΠ΅, Ρ ΡΠ΄ΡΡΡΠ°ΡΡΠ΅ΠΉ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡΡ ΡΠ²ΡΠ·ΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΠΌΠΈ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠ°ΠΌΠΈ. ΠΡ ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅ΡΠΏΠ΅ΡΡ ΠΎΡΡΡΡΡΡΠ²ΠΈΠ΅ IPv6 Π΄ΠΎΠΌΠ° ΠΈ Π½Π° ΡΠ°Π±ΠΎΡΠ΅?
Π£ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ friend-to-friend ΡΠ΅ΡΡ: Π²ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠΈ Π·Π°ΡΠ°Π½Π΅Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΠΈΠ·Π²Π΅ΡΡΠ½Ρ. ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ , ΡΡΠΎ ΡΠΈΠ»ΡΠ½ΠΎ Π²ΡΡ ΡΠΏΡΠΎΡΠ°Π΅Ρ: ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΠΈΠ»ΠΈΡΡ, Π½Π°ΡΠ»ΠΈ ΠΈΠ»ΠΈ Π½Π΅ Π½Π°ΡΠ»ΠΈ ΠΈΠΌΡ/ΠΊΠ»ΡΡ, ΠΎΡΠΊΠ»ΡΡΠΈΠ»ΠΈΡΡ ΠΈΠ»ΠΈ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ ΡΠ°Π±ΠΎΡΡ, Π·Π½Π°Ρ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°. ΠΠΎ-Π²ΡΠΎΡΡΡ , Π² ΠΎΠ±ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅, ΡΡΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΈ ΠΈΡΠΊΠ»ΡΡΠ°Π΅Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π°ΡΠ°ΠΊ.
ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ IM-Π° Π±ΡΠ΄Π΅Ρ Π±Π»ΠΈΠ·ΠΎΠΊ ΠΊ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΌ ΡΠ΅ΡΠ΅Π½ΠΈΡΠΌ
- in β Π² Π½Π΅Π³ΠΎ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡΡΡ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌΡΠ΅ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ;
- out β ΠΈΠ· Π½Π΅Π³ΠΎ ΡΠΈΡΠ°ΡΡΡΡ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌΡΠ΅ ΠΎΡ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ;
- state β ΡΠΈΡΠ°Ρ ΠΈΠ· Π½Π΅Π³ΠΎ, ΠΌΡ ΡΠ·Π½Π°ΡΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΡΠ½ Π»ΠΈ ΡΠ΅ΠΉΡΠ°Ρ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ, Π°Π΄ΡΠ΅Ρ/ΠΏΠΎΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ.
ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΡΠΎΠ·Π΄Π°ΡΡΡΡ conn ΡΠΎΠΊΠ΅Ρ, Π·Π°ΠΏΠΈΡΠ°Π² Π² ΠΊΠΎΡΠΎΡΡΠΉ Ρ ΠΎΡΡ ΠΏΠΎΡΡ, ΠΌΡ ΠΈΠ½ΠΈΡΠΈΠΈΡΡΠ΅ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊ ΡΠ΄Π°Π»ΡΠ½Π½ΠΎΠΌΡ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΡ.
|-- alice
| |-- in
| |-- out
| `-- state
|-- bob
| |-- in
| |-- out
| `-- state
`- conn
Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π΄Π΅Π»Π°ΡΡ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ IM ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ° ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°, Π²Π΅Π΄Ρ Π½Π° Π²ΠΊΡΡ ΠΈ ΡΠ²Π΅Ρ ΡΠΎΠ²Π°ΡΠΈΡΠ° Π½Π΅Ρ, ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡ Π½Π΅ ΡΠ³ΠΎΠ΄ΠΈΡΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ
ΠΠ° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅, suckless ΠΏΡΠΎΠ΅ΠΊΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ FIFO-ΡΠ°ΠΉΠ»Ρ. ΠΠΈΡΠ½ΠΎ Ρ Π½Π΅ ΡΠΌΠΎΠ³ ΠΏΠΎΠ½ΡΡΡ ΠΊΠ°ΠΊ Π² asyncio ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠ½ΠΎ Π±Π΅Π· ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΡΡΡΠ½ΠΎΠΉ ΠΏΠΎΠ΄Π»ΠΎΠΆΠΊΠΈ ΠΈΠ· Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΡΡ
ΡΡΠ΅Π΄ΠΎΠ² (Π΄Π»Ρ ΡΠ°ΠΊΠΈΡ
Π²Π΅ΡΠ΅ΠΉ Π΄Π°Π²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΠ·ΡΠΊ
ΠΠ΅ΡΠ²ΠΎΠ½Π°ΡΠ°Π»ΡΠ½ΡΠΉ Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΠΉ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»
Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ TCP: ΠΎΠ½ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ Π΄ΠΎΡΡΠ°Π²ΠΊΡ ΠΈ Π΅Ρ ΠΏΠΎΡΡΠ΄ΠΎΠΊ. UDP Π½Π΅ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ Π½ΠΈ ΡΠΎΠ³ΠΎ, Π½ΠΈ Π΄ΡΡΠ³ΠΎΠ³ΠΎ (ΡΡΠΎ Π±ΡΠ»ΠΎ Π±Ρ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡΡ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ), Π° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ
Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, Π² TCP Π½Π΅Ρ ΠΏΠΎΠ½ΡΡΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, Π° ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠΎΠΊΠ° Π±Π°ΠΉΡ. ΠΠΎΡΡΠΎΠΌΡ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠΈΠ΄ΡΠΌΠ°ΡΡ ΡΠΎΡΠΌΠ°Ρ Π΄Π»Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, ΡΡΠΎΠ±Ρ ΠΈΡ
ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΡΠ°Π·Π΄Π΅Π»ΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΎΠ±ΠΎΠΉ Π² ΡΡΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅. ΠΠΎΠΆΠ΅ΠΌ ΡΡΠ»ΠΎΠ²ΠΈΡΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠΌΠ²ΠΎΠ» ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄Π° ΡΡΡΠΎΠΊΠΈ. ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° ΠΏΠΎΠ΄ΠΎΠΉΠ΄ΡΡ, ΠΎΠ΄Π½Π°ΠΊΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΌΡ Π½Π°ΡΠ½ΡΠΌ ΡΠΈΡΡΠΎΠ²Π°ΡΡ Π½Π°ΡΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΡΡΠΎΡ ΡΠΈΠΌΠ²ΠΎΠ» ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΠ²ΠΈΡΡΡΡ Π³Π΄Π΅ ΡΠ³ΠΎΠ΄Π½ΠΎ Π² ΡΠΈΡΡΠΎΡΠ΅ΠΊΡΡΠ΅. Π ΡΠ΅ΡΡΡ
ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΠΎΠΏΡΠ»ΡΡΠ½Ρ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Ρ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΠΈΠ΅ ΡΠ½Π°ΡΠ°Π»Π° Π΄Π»ΠΈΠ½Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² Π±Π°ΠΉΡΠ°Ρ
. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Python ΠΈΠ· ΠΊΠΎΡΠΎΠ±ΠΊΠΈ Π΅ΡΡΡ xdrlib ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠ°Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠΌ ΡΠΎΡΠΌΠ°ΡΠΎΠΌ
ΠΡ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ ΠΈ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ TCP ΡΡΠ΅Π½ΠΈΠ΅ΠΌ β ΡΠΏΡΠΎΡΡΠΈΠΌ ΠΊΠΎΠ΄. Π§ΠΈΡΠ°Π΅ΠΌ Π² Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΡΠΈΠΊΠ»Π΅ Π΄Π°Π½Π½ΡΠ΅ ΠΈΠ· ΡΠΎΠΊΠ΅ΡΠ°, ΠΏΠΎΠΊΠ° Π½Π΅ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅ΠΌ ΠΏΠΎΠ»Π½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅. Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠΎΡΠΌΠ°ΡΠ° Π΄Π»Ρ ΡΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈ JSON Ρ XML. ΠΠΎ, ΠΊΠΎΠ³Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΡΡΡ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡ, ΡΠΎ Π΄Π°Π½Π½ΡΠ΅ ΠΏΡΠΈΠ΄ΡΡΡΡ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°ΡΡ ΠΈ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ β Π° ΡΡΠΎ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅Ρ Π±Π°ΠΉΡ-Π²-Π±Π°ΠΉΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΡΠ΅Π³ΠΎ Π½Π΅ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°ΡΡ JSON/XML (dumps ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΌΠΎΠΆΠ΅Ρ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ).
XDR ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΠΈΡ Π΄Π»Ρ ΡΠ°ΠΊΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ Ρ Π²ΡΠ±ΠΈΡΠ°Ρ ASN.1 Ρ DER-ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΈ
# 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() β ββββββββββββββββββ>β β β β MsgText() β β<ββββββββββββββββββ β β
IM Π±Π΅Π· ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΠΈ
ΠΠ°ΠΊ Ρ ΡΠΆΠ΅ Π³ΠΎΠ²ΠΎΡΠΈΠ», Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Ρ ΡΠΎΠΊΠ΅ΡΠ°ΠΌΠΈ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ asyncio Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°. ΠΠ±ΡΡΠ²ΠΈΠΌ ΡΡΠΎ ΠΌΡ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ Π² ΠΌΠΎΠΌΠ΅Π½Ρ Π·Π°ΠΏΡΡΠΊΠ°:
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(","))
ΠΠ°Π΄Π°ΡΡΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΠ΅ ΠΈΠΌΡ (—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))
Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ°. Π‘Π½Π°ΡΠ°Π»Π° ΠΎΠ½, ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ, ΠΎΡΠΊΡΡΠ²Π°Π΅Ρ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π΄ΠΎ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ Ρ ΠΎΡΡΠ°/ΠΏΠΎΡΡΠ° ΠΈ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ handshake ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΡΠΎ ΡΠ²ΠΎΠΈΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ:
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 # 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 # }}}
ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΡΡΠΎ ΠΏΡΠΈΡΠ΅Π΄ΡΠ΅Π΅ ΠΈΠΌΡ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° Π½Π°ΠΌ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ. ΠΡΠ»ΠΈ Π½Π΅Ρ, ΡΠΎ ΡΠ²ΡΠΌ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅. ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ Π½Π΅ Π±ΡΠ»ΠΎ Π»ΠΈ Ρ Π½Π°Ρ ΡΠΆΠ΅ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΎ Ρ Π½ΠΈΠΌ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ (ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊ Π²Π½ΠΎΠ²Ρ Π΄Π°Π» ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π½Π° ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊ Π½Π°ΠΌ) ΠΈ Π·Π°ΠΊΡΡΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ. Π 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 # 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 ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΈΡΡ ΠΎΠ΄ΡΡΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ (ΠΏΠΎΠ΄ΠΊΠ»Π°Π΄ΡΠ²Π°Π΅ΠΌΡΠ΅ Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΈΠ· in ΡΠΎΠΊΠ΅ΡΠ°), ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΡΠ΅Ρ ΠΈΡ Π² 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 ΠΎΡΠ΅ΡΠ΅Π΄Ρ, ΠΈΠ· ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΎΠ½ΠΈ Π±ΡΠ΄ΡΡ ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½Ρ Π² out ΡΠΎΠΊΠ΅Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°. ΠΠΎΡΠ΅ΠΌΡ Π½Π΅Π»ΡΠ·Ρ ΠΏΡΠΎΡΡΠΎ Π΄Π΅Π»Π°ΡΡ .read() ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅? ΠΠΎΡΠΎΠΌΡ ΡΡΠΎ Π½Π΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½Π° ΡΠΈΡΡΠ°ΡΠΈΡ, ΠΊΠΎΠ³Π΄Π° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΎΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π±ΡΠ΄ΡΡ Π°Π³ΡΠ΅Π³ΠΈΡΠΎΠ²Π°Π½Ρ Π² Π±ΡΡΠ΅ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ ΠΈ ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½Ρ ΠΎΠ΄Π½ΠΈΠΌ TCP-ΡΠ΅Π³ΠΌΠ΅Π½ΡΠΎΠΌ. ΠΠ΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ ΡΠΎ ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ²ΠΎΠ΅, Π° Π΄Π°Π»ΡΡΠ΅ Π² Π±ΡΡΠ΅ΡΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΠΎΡΡΠ°ΡΡΡΡ ΡΠ°ΡΡΡ ΠΎΡ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ. ΠΡΠΈ Π»ΡΠ±ΠΎΠΉ Π½Π΅ΡΡΠ°ΡΠ½ΠΎΠΉ ΡΠΈΡΡΠ°ΡΠΈΠΈ ΠΌΡ Π·Π°ΠΊΡΡΠ²Π°Π΅ΠΌ TCP-ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ msg_sender ΠΊΠΎΡΡΡΠΈΠ½Ρ (ΠΏΠΎΡΡΠ»ΠΊΠΎΠΉ None Π² 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)
ΠΠ΅ΡΠ½ΡΠΌΡΡ ΠΊ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌΡ ΠΊΠΎΠ΄Ρ. ΠΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π²ΡΠ΅Ρ ΠΊΠΎΡΡΡΠΈΠ½ Π² ΠΌΠΎΠΌΠ΅Π½Ρ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΌΡ ΡΡΠ°ΡΡΡΠ΅ΠΌ 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("Listening on: %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) β ΡΠ°ΠΊΡ ΠΏΡΠΎΠΏΠ°ΠΆΠΈ ΠΈΠ»ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ (ΠΈ ΠΌΡ ΡΠ΅ΡΠ°Π΅ΠΌ ΠΎΠ±ΡΡΠ²Π°ΡΡ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅);
- ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΈ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠΎΠ² ΠΏΠΎ Π·Π°ΡΠ°Π½Π΅Π΅ Π²Π±ΠΈΡΡΠΌ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ ΠΊΠ»ΡΡΠ°ΠΌ β ΠΌΡ ΡΠΆΠ΅ ΡΠ΅ΡΠΈΠ»ΠΈ ΡΠ°Π½Π΅Π΅, ΡΡΠΎ Π΄Π΅Π»Π°Π΅ΠΌ friend-to-friend ΡΠ΅ΡΡ. Π’ΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠ»Π΅ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ ΠΌΡ ΠΏΠΎΠΉΠΌΡΠΌ Ρ ΠΊΠ΅ΠΌ ΠΎΠ±ΡΠ°Π΅ΠΌΡΡ;
- Π½Π°Π»ΠΈΡΠΈΠ΅
perfect forward secrecy ΡΠ²ΠΎΠΉΡΡΠ²Π° (PFS) β ΠΊΠΎΠΌΠΏΡΠΎΠΌΠ΅ΡΠ°ΡΠΈΡ Π½Π°ΡΠ΅Π³ΠΎ Π΄ΠΎΠ»Π³ΠΎΠΆΠΈΠ²ΡΡΠ΅Π³ΠΎ ΠΊΠ»ΡΡΠ° ΠΏΠΎΠ΄ΠΏΠΈΡΠΈ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡΡ ΠΊ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΡΠ΅Π½ΠΈΡ Π²ΡΠ΅ΠΉ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠΊΠΈ. ΠΠ°ΠΏΠΈΡΡ ΠΏΠ΅ΡΠ΅Ρ Π²Π°ΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΡΠ°ΡΠΈΠΊΠ° ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ Π±Π΅ΡΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ; - Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ/Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ (ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΡ ΠΈ ΡΡΠΊΠΎΠΏΠΎΠΆΠ°ΡΠΈΡ) ΡΠΎΠ»ΡΠΊΠΎ Π² ΠΏΡΠ΅Π΄Π΅Π»Π°Ρ ΠΎΠ΄Π½ΠΎΠΉ TCP-ΡΠ΅ΡΡΠΈΠΈ. ΠΡΡΠ°Π²ΠΊΠ° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Π½Π½ΡΡ /Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΈΠ· Π΄ΡΡΠ³ΠΎΠΉ ΡΠ΅ΡΡΠΈΠΈ (Π΄Π°ΠΆΠ΅ Ρ ΡΡΠΈΠΌ ΠΆΠ΅ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠΎΠΌ) Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ;
- ΠΏΠ°ΡΡΠΈΠ²Π½ΡΠΉ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΈΠ΄Π΅ΡΡ Π½ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠ² ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ, Π½ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΡ Π΄ΠΎΠ»Π³ΠΎΠΆΠΈΠ²ΡΡΠΈΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ, Π½ΠΈ Ρ ΡΡΠ΅ΠΉ ΠΎΡ Π½ΠΈΡ . ΠΠ΅ΠΊΠ°Ρ Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΡΡΡ ΠΎΡ ΠΏΠ°ΡΡΠΈΠ²Π½ΠΎΠ³ΠΎ Π½Π°Π±Π»ΡΠ΄Π°ΡΠ΅Π»Ρ.
Π£Π΄ΠΈΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ, Π½ΠΎ ΡΡΠΎΡ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ Π²ΡΠ΅ Ρ
ΠΎΡΡΡ ΠΈΠΌΠ΅ΡΡ Π² Π»ΡΠ±ΠΎΠΌ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π΅ ΡΡΠΊΠΎΠΏΠΎΠΆΠ°ΡΠΈΡ, ΠΈ ΠΊΡΠ°ΠΉΠ½Π΅ ΠΌΠ°Π»ΠΎ ΠΈΠ· ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½Π½ΠΎΠ³ΠΎ Π² ΠΈΡΠΎΠ³Π΅ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π΄Π»Ρ Β«Π΄ΠΎΠΌΠΎΡΠΎΡΠ΅Π½Π½ΡΡ
Β» ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΎΠ². ΠΠΎΡ ΠΈ ΡΠ΅ΠΉΡΠ°Ρ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ ΠΈΠ·ΠΎΠ±ΡΠ΅ΡΠ°ΡΡ Π½ΠΎΠ²ΠΎΠ³ΠΎ. Π― Π±Ρ ΠΎΠ΄Π½ΠΎΠ·Π½Π°ΡΠ½ΠΎ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π» ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
ΠΠ°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠΏΡΠ»ΡΡΠ½Ρ Π΄Π²Π° ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°:
TLS β ΡΠ»ΠΎΠΆΠ½Π΅ΠΉΡΠΈΠΉ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Ρ Π΄Π»ΠΈΠ½Π½ΠΎΠΉ ΠΈΡΡΠΎΡΠΈΠ΅ΠΉ Π±Π°Π³ΠΎΠ², ΠΊΠΎΡΡΠΊΠΎΠ², ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΠ΅ΠΉ, ΠΏΠ»ΠΎΡ ΠΎΠΉ ΠΏΡΠΎΠ΄ΡΠΌΠ°Π½Π½ΠΎΡΡΠΈ, ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΈ Π½Π΅Π΄ΠΎΡΡΡΠΎΠ² (Π²ΠΏΡΠΎΡΠ΅ΠΌ, ΠΊ TLS 1.3 ΡΡΠΎ ΠΌΠ°Π»ΠΎ ΠΎΡΠ½ΠΎΡΠΈΡΡΡ). ΠΠΎ Π½Π΅ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ ΠΈΠ·-Π·Π° ΠΏΠ΅ΡΠ΅ΡΡΠ»ΠΎΠΆΠ½ΡΠ½Π½ΠΎΡΡΠΈ.-
IPsec ΡIKE β Π½Π΅ ΠΈΠΌΠ΅ΡΡ ΡΠ΅ΡΡΡΠ·Π½ΡΡ ΠΊΡΠΈΠΏΡΠΎΠ³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ, Ρ ΠΎΡΡ ΡΠΎΠΆΠ΅ Π½Π΅ ΠΏΡΠΎΡΡΡ. ΠΡΠ»ΠΈ ΠΏΠΎΡΠΈΡΠ°ΡΡ ΠΏΡΠΎ IKEv1 ΠΈ IKEv2, ΡΠΎ ΠΈΡ ΠΈΡΡΠΎΠΊΠΎΠΌ ΡΠ²Π»ΡΡΡΡΡSTS , 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 ΠΈ ΠΏΠ΅ΡΠ΅ΠΏΠΎΠ΄ΠΏΠΈΡΠ°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΊΠ»ΡΡΠΎΠΌ Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠΌ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°. ΠΠ»Ρ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ΅Π½ΠΈΡ
βββββββ βββββββ β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 Π°ΡΠ°ΠΊ ΠΏΡΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΡΡΠ΅ΠΌΠ΅ΡΠ½ΡΡ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ. ΠΠ·-Π·Π° binding-Π° ΠΌΠ΅ΠΆΠ΄Ρ cookie ΠΈ ΡΡΠ΅ΠΌΠ΅ΡΠ½ΡΠΌ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΌ ΠΊΠ»ΡΡΠΎΠΌ, ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ ΠΊΠ»ΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΠ³ΠΎ ΡΡΠ°ΡΡΠ½ΠΈΠΊΠ° ΠΌΠΎΠΆΠ½ΠΎ ΡΠ±ΡΠ°ΡΡ ΠΈΠ· ΠΏΠΎΠ΄ΠΏΠΈΡΠΈ Π·Π° Π½Π΅Π½Π°Π΄ΠΎΠ±Π½ΠΎΡΡΡΡ.
βββββββ βββββββ βPeerAβ βPeerBβ ββββ¬βββ ββββ¬βββ β IdA, PubA, CookieA β βββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ>β βSignPrvA, SignPubA = load()β β β βPrvA, PubA = DHgen() β β β βββββββββββββββββββββββββββββ βIdB, PubB, CookieB, sign(SignPrvB, (CookieA, CookieB, PubB)), MAC(IdB) β βββββββββββββββββββββββββββββ β<βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ βSignPrvB, SignPubB = load()β β β βPrvB, PubB = DHgen() β β β βββββββββββββββββββββββββββββ β β βββββββββββββββββββββββ β sign(SignPrvA, (CookieB, CookieA, PubA)), MAC(IdA) β βKey = DH(PrvA, PubB) β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ>β β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, ...)β β β βββββββββββββββββββββββ β β
- ΠΠ»Ρ ΠΏΠΎΠ΄ΠΏΠΈΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΠΠ‘Π’ Π
34.10-2012 Π°Π»Π³ΠΎΡΠΈΡΠΌ Ρ 256-Π±ΠΈΡ ΠΊΠ»ΡΡΠ°ΠΌΠΈ. - ΠΠ»Ρ Π²ΡΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΠ±ΡΠ΅Π³ΠΎ ΠΊΠ»ΡΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ 34.10-2012 VKO.
- Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ MAC ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ CMAC. Π’Π΅Ρ
Π½ΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠΎ ΠΎΡΠΎΠ±ΡΠΉ ΡΠ΅ΠΆΠΈΠΌ ΡΠ°Π±ΠΎΡΡ Π±Π»ΠΎΡΠ½ΠΎΠ³ΠΎ ΡΠΈΡΡΠ°, ΠΎΠΏΠΈΡΠ°Π½Π½ΡΠΉ Π² ΠΠΠ‘Π’ Π 34.13-2015. Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΡΠ΅ΠΆΠΈΠΌΠ° β
ΠΡΠ·Π½Π΅ΡΠΈΠΊ (34.12-2015). - Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Ρ
ΡΡ ΠΎΡ Π΅Π³ΠΎ ΠΏΡΠ±Π»ΠΈΡΠ½ΠΎΠ³ΠΎ ΠΊΠ»ΡΡΠ°. Π ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Ρ
ΡΡΠ° ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ
Π‘ΡΡΠΈΠ±ΠΎΠ³-256 (34.11-2012 256 Π±ΠΈΡ).
ΠΠΎΡΠ»Π΅ ΡΡΠΊΠΎΠΏΠΎΠΆΠ°ΡΠΈΡ Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½ ΠΎΠ±ΡΠΈΠΉ ΠΊΠ»ΡΡ. ΠΠ³ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ. ΠΡΠ° ΡΠ°ΡΡΡ ΡΠΎΠ²ΡΠ΅ΠΌ ΠΏΡΠΎΡΡΠ°Ρ ΠΈ Π² Π½Π΅ΠΉ ΡΠ»ΠΎΠΆΠ½ΠΎ ΠΎΡΠΈΠ±ΠΈΡΡΡΡ: ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠΈΡΡΠ΅ΠΌ ΡΡΡΡΡΠΈΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, ΡΠΈΡΡΡΠ΅ΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΡΠ΅ΠΌ (MAC) ΡΡΡΡΡΠΈΠΊ ΠΈ ΡΠΈΡΡΠΎΡΠ΅ΠΊΡΡ, ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ. ΠΡΠΈ ΠΏΡΠΈΡΠΌΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΡΡΠΎ ΡΡΡΡΡΠΈΠΊ ΠΈΠΌΠ΅Π΅Ρ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΡΠ΅ΠΌ ΡΠΈΡΡΠΎΡΠ΅ΠΊΡΡ Ρ ΡΡΡΡΡΠΈΠΊΠΎΠΌ, Π΄Π΅ΡΠΈΡΡΡΠ΅ΠΌ. ΠΠ°ΠΊΠΈΠΌ ΠΊΠ»ΡΡΠΎΠΌ ΡΠΈΡΡΠΎΠ²Π°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΡΡΠΊΠΎΠΏΠΎΠΆΠ°ΡΠΈΡ, ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΠ΅, ΠΊΠ°ΠΊΠΈΠΌ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ? ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΊΠ»ΡΡ Π΄Π»Ρ Π²ΡΠ΅Ρ ΡΡΠΈΡ Π·Π°Π΄Π°Ρ ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΈ Π½Π΅ΡΠ°Π·ΡΠΌΠ½ΠΎ. ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π²ΡΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΊΠ»ΡΡΠΈ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ
KDF (key derivation function). ΠΠΏΡΡΡ ΠΆΠ΅, Π½Π΅ Π±ΡΠ΄Π΅ΠΌ ΠΌΡΠ΄ΡΠΈΡΡ ΠΈ ΡΡΠΎ-ΡΠΎ ΠΈΠ·ΠΎΠ±ΡΠ΅ΡΠ°ΡΡ:HKDF Π΄Π°Π²Π½ΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½Π°, Ρ ΠΎΡΠΎΡΠΎ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°Π½Π° ΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ. Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, Π² ΡΠΎΠ΄Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ΅ Python Π½Π΅Ρ ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌhkdf ΠΏΠ°ΠΊΠ΅Ρ. HKDF Π²Π½ΡΡΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡHMAC , ΠΊΠΎΡΠΎΡΡΠΉ, Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Ρ ΡΡ-ΡΡΠ½ΠΊΡΠΈΡ. ΠΡΠΈΠΌΠ΅Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π½Π° 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 Π΄Π°Π½Π½ΡΡ :
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), } # }}}
ΠΡΠΈΠ²Π°ΡΠ½ΡΠΉ ΠΊΠ»ΡΡ 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 ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ Ρ ΡΡ-ΡΡΠ½ΠΊΡΠΈΠΉ.
ΠΠ°ΠΊ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»Π°ΡΡ ΠΊΠΎΡΡΡΠΈΠ½Π° ΠΈΠ½ΠΈΡΠΈΠ°ΡΠΎΡΠ°? ΠΡΡ, ΠΊΠ°ΠΊ ΠΏΠΎ ΡΡ Π΅ΠΌΠ΅ ΡΡΠΊΠΎΠΏΠΎΠΆΠ°ΡΠΈΡ: Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΠΌ cookie (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 # 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()
- ΠΆΠ΄ΡΠΌ ΠΎΡΠ²Π΅ΡΠ° ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅ΠΌ ΠΏΡΠΈΡΠ΅Π΄ΡΠ΅Π΅ Msg ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅;
- ΡΠ±Π΅ΠΆΠ΄Π°Π΅ΠΌΡΡ ΡΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ handshake1;
- Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅ΠΌ ΡΡΠ΅ΠΌΠ΅ΡΠ½ΡΠΉ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ ΠΊΠ»ΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ ΠΈ Π²ΡΡΠΈΡΠ»ΡΠ΅ΠΌ ΡΠ΅ΡΡΠΈΠΎΠ½Π½ΡΠΉ ΠΊΠ»ΡΡ;
- Π²ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ ΡΠΈΠΌΠΌΠ΅ΡΡΠΈΡΠ½ΡΠ΅ ΠΊΠ»ΡΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ 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 # 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 ΡΡΠΎ 64-Π±ΠΈΡ ΡΠΈΡΠ»ΠΎ (urandom(8)), ΠΊΠΎΡΠΎΡΠΎΠ΅ ΡΠΎΠΆΠ΅ ΡΡΠ΅Π±ΡΠ΅Ρ Π΄Π΅ΡΠ΅ΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ· Π±Π°ΠΉΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ gost3410_vko.ukm_unmarshal(). VKO ΡΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ 34.10-2012 256-Π±ΠΈΡ ΡΡΠΎ gost3410_vko.kek_34102012256() (KEK β key encryption key).
ΠΡΡΠ°Π±ΠΎΡΠ°Π½Π½ΡΠΉ ΡΠ΅ΡΡΠΈΠΎΠ½Π½ΡΠΉ ΠΊΠ»ΡΡ ΡΠΆΠ΅ ΡΠ²Π»ΡΠ΅ΡΡΡ 256-Π±ΠΈΡ Π±Π°ΠΉΡΠΎΠ²ΠΎΠΉ ΠΏΡΠ΅Π²Π΄ΠΎΡΠ»ΡΡΠ°ΠΉΠ½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡΡ. ΠΠΎΡΡΠΎΠΌΡ Π΅Π³ΠΎ ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² HKDF ΡΡΠ½ΠΊΡΠΈΠΈ. Π’Π°ΠΊ ΠΊΠ°ΠΊ GOST34112012256 ΡΠ΄ΠΎΠ²Π»Π΅ΡΠ²ΠΎΡΡΠ΅Ρ hashlib ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ, ΡΠΎ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² Hkdf ΠΊΠ»Π°ΡΡΠ΅. Π‘ΠΎΠ»Ρ (ΠΏΠ΅ΡΠ²ΡΠΉ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ Hkdf) ΠΌΡ Π½Π΅ ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π²ΡΡΠ°Π±ΠΎΡΠ°Π½Π½ΡΠΉ ΠΊΠ»ΡΡ ΠΈΠ·-Π·Π° ΡΡΠ΅ΠΌΠ΅ΡΠ½ΠΎΡΡΠΈ ΡΡΠ°ΡΡΠ²ΡΡΡΠΈΡ ΠΊΠ»ΡΡΠ΅Π²ΡΡ ΠΏΠ°Ρ Π±ΡΠ΄Π΅Ρ ΡΠ°Π·Π½ΡΠΌ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΠ΅ΡΡΠΈΠΈ ΠΈ Π² Π½ΡΠΌ ΡΠΆΠ΅ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΠ½ΡΡΠΎΠΏΠΈΠΈ. kdf.expand() ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΡΠΆΠ΅ Π²ΡΠ΄Π°ΡΡ ΠΊΠ»ΡΡΠΈ Π΄Π»ΠΈΠ½ΠΎΠΉ 256-Π±ΠΈΡ, ΡΡΠ΅Π±ΡΠ΅ΠΌΡΠ΅ Π΄Π»Ρ ΠΡΠ·Π½Π΅ΡΠΈΠΊΠ° Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ.
ΠΠ°Π»Π΅Π΅ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡΡ TBE ΠΈ TBS ΡΠ°ΡΡΠΈ ΠΏΡΠΈΡΠ΅Π΄ΡΠ΅Π³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ:
- Π²ΡΡΠΈΡΠ»ΡΠ΅ΡΡΡ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΡΡΡ MAC Π½Π°Π΄ ΠΏΡΠΈΡΠ΅Π΄ΡΠΈΠΌ ΡΠΈΡΡΠΎΡΠ΅ΠΊΡΡΠΎΠΌ;
- Π΄Π΅ΡΠΈΡΡΡΠ΅ΡΡΡ ΡΠΈΡΡΠΎΡΠ΅ΠΊΡΡ;
- Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅ΡΡΡ TBE ΡΡΡΡΠΊΡΡΡΠ°;
- ΠΈΠ· Π½Π΅Ρ Π±Π΅ΡΡΡΡΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ° ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΡΡΡ ΠΈΠ·Π²Π΅ΡΡΠ΅Π½ Π»ΠΈ ΠΎΠ½ Π½Π°ΠΌ Π²ΠΎΠΎΠ±ΡΠ΅;
- Π²ΡΡΠΈΡΠ»ΡΠ΅ΡΡΡ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡΡ MAC Π½Π°Π΄ ΡΡΠΈΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ;
- ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΡΡΡ ΠΏΠΎΠ΄ΠΏΠΈΡΡ Π½Π°Π΄ TBS ΡΡΡΡΠΊΡΡΡΠΎΠΉ, Π² ΠΊΠΎΡΠΎΡΡΡ Π²Ρ ΠΎΠ΄ΡΡ cookie ΠΎΠ±Π΅ΠΈΡ ΡΡΠΎΡΠΎΠ½ ΠΈ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΠΉ ΡΡΠ΅ΠΌΠ΅ΡΠ½ΡΠΉ ΠΊΠ»ΡΡ ΠΏΡΠΎΡΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ. ΠΠΎΠ΄ΠΏΠΈΡΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΡΡΡ Π΄ΠΎΠ»Π³ΠΎΠΆΠΈΠ²ΡΡΠΈΠΌ ΠΊΠ»ΡΡΠΎΠΌ ΠΏΠΎΠ΄ΠΏΠΈΡΠΈ ΡΠΎΠ±Π΅ΡΠ΅Π΄Π½ΠΈΠΊΠ°.
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"]
ΠΠ°ΠΊ ΡΠΆΠ΅ ΠΏΠΈΡΠ°Π» Π²ΡΡΠ΅, 34.13-2015 ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅
ΡΠ΅ΠΆΠΈΠΌΡ ΡΠ°Π±ΠΎΡΡ Π±Π»ΠΎΡΠ½ΡΡ ΡΠΈΡΡΠΎΠ² ΠΈΠ· 34.12-2015. Π‘ΡΠ΅Π΄ΠΈ Π½ΠΈΡ Π΅ΡΡΡ ΡΠ΅ΠΆΠΈΠΌ Π²ΡΡΠ°Π±ΠΎΡΠΊΠΈ ΠΈΠΌΠΈΡΠΎΠ²ΡΡΠ°Π²ΠΊΠΈ, Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ MAC-Π°. Π PyGOST ΡΡΠΎ gost3413.mac(). ΠΡΠΎΡ ΡΠ΅ΠΆΠΈΠΌ ΡΡΠ΅Π±ΡΠ΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ (ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡΠ°Ρ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΠ°Ρ ΠΎΠ΄ΠΈΠ½ Π±Π»ΠΎΠΊ Π΄Π°Π½Π½ΡΡ ), ΡΠ°Π·ΠΌΠ΅ΡΠ° ΡΠΈΡΡΠΎΠ±Π»ΠΎΠΊΠ° ΠΈ, ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎ, ΡΠ°ΠΌΠΈΡ Π΄Π°Π½Π½ΡΡ . ΠΠΎΡΠ΅ΠΌΡ Π½Π΅Π»ΡΠ·Ρ hardcode-ΠΈΡΡ ΡΠ°Π·ΠΌΠ΅Ρ ΡΠΈΡΡΠΎΠ±Π»ΠΎΠΊΠ°? 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-Π° Π½Π΅Π»ΡΠ·Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΡΠ½ΠΎΠ΅ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ (==) Π±Π°ΠΉΡΠΎΠ²ΡΡ ΡΡΡΠΎΠΊ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π΄Π°ΡΡ ΡΡΠ΅ΡΠΊΠΈ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ, ΡΡΠΎ, Π² ΠΎΠ±ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅, ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡΡ ΠΊ ΡΠ°ΡΠ°Π»ΡΠ½ΡΠΌ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡΠΌ ΡΠΈΠΏΠ°
BEAST Π°ΡΠ°ΠΊΠΈ Π½Π° 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 # 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)
ΠΠΎΠ³Π΄Π° ΡΠ΅ΡΡΠΈΡ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π°, ΡΠΎ Π²ΡΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ ΡΡΠ°Π½ΡΠΏΠΎΡΡΠ½ΡΠ΅ ΠΊΠ»ΡΡΠΈ (ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΊΠ»ΡΡ Π΄Π»Ρ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ, Π΄Π»Ρ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ, Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· ΡΡΠΎΡΠΎΠ½), ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΡΡΡ ΠΡΠ·Π½Π΅ΡΠΈΠΊ Π΄Π»Ρ Π΄Π΅ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ 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 ΠΊΠΎΡΡΡΠΈΠ½Π° ΡΠ΅ΠΏΠ΅ΡΡ ΡΠΈΡΡΡΠ΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΏΠ΅ΡΠ΅Π΄ ΠΎΡΠΏΡΠ°Π²ΠΊΠΎΠΉ Π² TCP-ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅. Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΌΠΎΠ½ΠΎΡΠΎΠ½Π½ΠΎ Π²ΠΎΠ·ΡΠ°ΡΡΠ°ΡΡΠΈΠΉ nonce, ΡΠ°ΠΊΠΆΠ΅ ΡΠ²Π»ΡΡΡΠΈΠΉΡΡ ΠΈ Π²Π΅ΠΊΡΠΎΡΠΎΠΌ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΈ ΡΠΈΡΡΠΎΠ²Π°Π½ΠΈΠΈ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΡΡΡΡΠΈΠΊΠ°. Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΈ Π±Π»ΠΎΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎ Π±ΡΠ΄ΡΡ ΠΎΡΠ»ΠΈΡΠ°ΡΡΠΈΠ΅ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΡΡΡΡΠΈΠΊΠ°.
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 += 1
ΠΡΠΈΡ ΠΎΠ΄ΡΡΠΈΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ ΠΊΠΎΡΡΡΠΈΠ½ΠΎΠΉ msg_receiver, Π·Π°Π½ΠΈΠΌΠ°ΡΡΠ΅ΠΉΡΡ Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠ΅ΠΉ ΠΈ Π΄Π΅ΡΠΈΡΡΠ°ΡΠΈΠ΅ΠΉ:
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)
ΠΠ°ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
GOSTIM ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π² ΡΡΠ΅Π±Π½ΡΡ ΡΠ΅Π»ΡΡ (ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π½Π΅ ΠΏΠΎΠΊΡΡΡ ΡΠ΅ΡΡΠ°ΠΌΠΈ, ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ)! ΠΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°ΡΠ°ΡΡ
ΡΡΡ (Π‘ΡΡΠΈΠ±ΠΎΠ³-256 Ρ ΡΡ: 995bbd368c04e50a481d138c5fa2e43ec7c89bc77743ba8dbabee1fde45de120). ΠΠ°ΠΊ ΠΈ Π²ΡΠ΅ ΠΌΠΎΠΈ ΠΏΡΠΎΠ΅ΠΊΡΡ, ΡΠΈΠΏΠ°GoGOST ,PyDERASN ,NNCP ,GoVPN , GOSTIM ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡΠΌ ΠΠ , ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ΅ΠΌΡΠΌ Π½Π° ΡΡΠ»ΠΎΠ²ΠΈΡΡGPLv3+ .Π‘Π΅ΡΠ³Π΅ΠΉ ΠΠ°ΡΠ²Π΅Π΅Π² ,ΡΠΈΡΡΠΎΠΏΠ°Π½ΠΊ , ΡΠ»Π΅Π½Π€ΠΎΠ½Π΄Π° Π‘ΠΠ , Python/Go-ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ, Π³Π»Π°Π²Π½ΡΠΉ ΡΠΏΠ΅ΡΠΈΠ°Π»ΠΈΡΡΠ€ΠΠ£Π Β«ΠΠ’Π¦ βΠΡΠ»Π°Ρβ . - ΠΠ»Ρ ΠΏΠΎΠ΄ΠΏΠΈΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΠΠ‘Π’ Π
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com