GOSTIM: GOST เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเซ€ เชธเชพเชฅเซ‡ เชเช• เชธเชพเช‚เชœเซ‡ P2P F2F E2EE IM

เชตเชฟเช•เชพเชธเช•เชฐเซเชคเชพ เชฌเชจเชตเซเช‚ PyGOST เชชเซเชธเซเชคเช•เชพเชฒเชฏเซ‹ (เชถเซเชฆเซเชง เชชเชพเชฏเชฅเซ‹เชจเชฎเชพเช‚ GOST เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเชฟเช• เชชเซเชฐเชฟเชฎเชฟเชŸเชฟเชตเซเชธ), เชฎเชจเซ‡ เช˜เชฃเซ€ เชตเชพเชฐ เช˜เซ‚เช‚เชŸเชฃ เชชเชฐ เชธเซŒเชฅเซ€ เชธเชฐเชณ เชธเซเชฐเช•เซเชทเชฟเชค เชฎเซ‡เชธเซ‡เชœเชฟเช‚เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเซเช‚ เชคเซ‡ เชตเชฟเชถเซ‡ เชชเซเชฐเชถเซเชจเซ‹ เชชเซเชฐเชพเชชเซเชค เชฅเชพเชฏ เช›เซ‡. เช˜เชฃเชพ เชฒเซ‹เช•เซ‹ เชเชชเซเชฒเชพเช‡เชก เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเซ€เชจเซ‡ เชเช•เชฆเชฎ เชธเชฐเชณ เชฎเชพเชจเซ‡ เช›เซ‡, เช…เชจเซ‡ เชฌเซเชฒเซ‹เช• เชธเชพเช‡เชซเชฐ เชชเชฐ .encrypt() เชจเซ‡ เช•เซ‰เชฒ เช•เชฐเชตเซเช‚ เชคเซ‡เชจเซ‡ เชธเช‚เชšเชพเชฐ เชšเซ‡เชจเชฒ เชชเชฐ เชธเซเชฐเช•เซเชทเชฟเชค เชฐเซ€เชคเซ‡ เชฎเซ‹เช•เชฒเชตเชพ เชฎเชพเชŸเซ‡ เชชเซ‚เชฐเชคเซเช‚ เชนเชถเซ‡. เช…เชจเซเชฏ เชฒเซ‹เช•เซ‹ เชฎเชพเชจเซ‡ เช›เซ‡ เช•เซ‡ เชเชชเซเชฒเชพเช‡เชก เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเซ€ เช เชฅเซ‹เชกเชพ เชฒเซ‹เช•เซ‹เชจเซเช‚ เชจเชธเซ€เชฌ เช›เซ‡, เช…เชจเซ‡ เชคเซ‡ เชธเซเชตเซ€เช•เชพเชฐเซเชฏ เช›เซ‡ เช•เซ‡ เช“เชฒเชฟเชฎเซเชชเชฟเชฏเชพเชก-เช—เชฃเชฟเชคเชถเชพเชธเซเชคเซเชฐเซ€เช“ เชธเชพเชฅเซ‡ เชŸเซ‡เชฒเชฟเช—เซเชฐเชพเชฎ เชœเซ‡เชตเซ€ เชธเชฎเซƒเชฆเซเชง เช•เช‚เชชเชจเซ€เช“ เช…เชฎเชฒ เช•เชฐเซ€ เชถเช•เชคเชพ เชจเชฅเซ€ เชธเซเชฐเช•เซเชทเชฟเชค เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ.

เช† เชฌเชงเชพเช เชฎเชจเซ‡ เช† เชฒเซ‡เช– เชฒเช–เชตเชพ เชฎเชพเชŸเซ‡ เชชเซเชฐเซ‹เชคเซเชธเชพเชนเชฟเชค เช•เชฐเซเชฏเซเช‚ เช•เซ‡ เชคเซ‡ เชฌเชคเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เช•เซ‡ เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเชฟเช• เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เช…เชจเซ‡ เชธเซเชฐเช•เซเชทเชฟเชค IM เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเซเช‚ เชเชŸเชฒเซเช‚ เชฎเซเชถเซเช•เซ‡เชฒ เช•เชพเชฐเซเชฏ เชจเชฅเซ€. เชœเซ‹ เช•เซ‡, เชคเชฎเชพเชฐเชพ เชชเซ‹เชคเชพเชจเชพ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เช…เชจเซ‡ เชฎเซเช–เซเชฏ เช•เชฐเชพเชฐ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชจเซ€ เชถเซ‹เชง เช•เชฐเชตเซ€ เชคเซ‡ เชฏเซ‹เช—เซเชฏ เชจเชฅเซ€.

GOSTIM: GOST เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเซ€ เชธเชพเชฅเซ‡ เชเช• เชธเชพเช‚เชœเซ‡ P2P F2F E2EE IM
เชฒเซ‡เช– เชฒเช–เชถเซ‡ เชธเชนเชญเชพเช—เซ€ เชฅเซ€ เชธเชนเชญเชพเช—เซ€, เชฎเชฟเชคเซเชฐ เชฅเซ€ เชฎเชฟเชคเซเชฐ, เชเชจเซเชก-เชŸเซ-เชเชจเซเชก เชเชจเซเช•เซเชฐเชฟเชชเซเชŸเซ‡เชก เชธเชพเชฅเซ‡ เช‡เชจเซเชธเซเชŸเชจเซเชŸ เชฎเซ‡เชธเซ‡เชจเซเชœเชฐ เชธเชฟเช—เซเชฎเชพ-I เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เช…เชจเซ‡ เชฎเซเช–เซเชฏ เช•เชฐเชพเชฐ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ (เชœเซ‡เชจเชพ เช†เชงเชพเชฐเซ‡ เชคเซ‡ เช…เชฎเชฒเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ IPsec IKE), เชซเช•เซเชค GOST เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเชฟเช• เช…เชฒเซเช—เซ‹เชฐเชฟเชงเชฎเซเชธ PyGOST เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เช…เชจเซ‡ ASN.1 เชฎเซ‡เชธเซ‡เชœ เชเชจเซเช•เซ‹เชกเชฟเช‚เช— เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ PyDERASN (เชœเซ‡เชจเชพ เชตเชฟเชถเซ‡ เชนเซเช‚ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เชชเชนเซ‡เชฒเชพเช‚ เชฒเช–เซเชฏเซเช‚ เชนเชคเซเช‚). เชชเซ‚เชฐเซเชตเชถเชฐเชค: เชคเซ‡ เชเชŸเชฒเซเช‚ เชธเชฐเชณ เชนเซ‹เชตเซเช‚ เชœเซ‹เชˆเช เช•เซ‡ เชคเซ‡ เชเช• เชธเชพเช‚เชœเซ‡ (เช…เชฅเชตเชพ เช•เชพเชฎเชจเชพ เชฆเชฟเชตเชธเซ‡) เชถเชฐเซ‚เช†เชคเชฅเซ€ เชฒเช–เซ€ เชถเช•เชพเชฏ, เช…เชจเซเชฏเชฅเชพ เชคเซ‡ เชนเชตเซ‡ เชธเชฐเชณ เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎ เชจเชฅเซ€. เชคเซ‡เชฎเชพเช‚ เชธเช‚เชญเชตเชคเชƒ เชญเซ‚เชฒเซ‹, เชฌเชฟเชจเชœเชฐเซ‚เชฐเซ€ เช—เซ‚เช‚เชšเชตเชฃเซ‹, เช–เชพเชฎเซ€เช“ เช›เซ‡, เช‰เชชเชฐเชพเช‚เชค เชเชธเชฟเชจเซเชธเชฟเชฏเซ‹ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช† เชฎเชพเชฐเซ‹ เชชเซเชฐเชฅเชฎ เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎ เช›เซ‡.

IM เชกเชฟเชเชพเช‡เชจ

เชชเซเชฐเชฅเชฎ, เช†เชชเชฃเซ‡ เช เชธเชฎเชœเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เช•เซ‡ เช†เชชเชฃเซเช‚ IM เช•เซ‡เชตเซเช‚ เชฆเซ‡เช–เชพเชถเซ‡. เชธเชฐเชณเชคเชพ เชฎเชพเชŸเซ‡, เชธเชนเชญเชพเช—เซ€เช“เชจเซ€ เช•เซ‹เชˆเชชเชฃ เชถเซ‹เชง เชตเชฟเชจเชพ, เชคเซ‡เชจเซ‡ เชชเซ€เช…เชฐ-เชŸเซ-เชชเซ€เช…เชฐ เชจเซ‡เชŸเชตเชฐเซเช• เชฌเชจเชตเชพ เชฆเซ‹. เช…เชฎเซ‡ เชตเซเชฏเช•เซเชคเชฟเช—เชค เชฐเซ€เชคเซ‡ เชธเซ‚เชšเชตเซ€เชถเซเช‚ เช•เซ‡ เช•เชฏเซเช‚ เชธเชฐเชจเชพเชฎเซเช‚: เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐ เชธเชพเชฅเซ‡ เชตเชพเชคเชšเซ€เชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡เชจเซเช‚ เชชเซ‹เชฐเซเชŸ.

เชนเซเช‚ เชธเชฎเชœเซเช‚ เช›เซเช‚ เช•เซ‡, เช† เชธเชฎเชฏเซ‡, เชฌเซ‡ เชฎเชจเชธเซเชตเซ€ เช•เชฎเซเชชเซเชฏเซเชŸเชฐเซเชธ เชตเชšเซเชšเซ‡ เชธเซ€เชงเซ‹ เชธเช‚เชšเชพเชฐ เช‰เชชเชฒเชฌเซเชง เช›เซ‡ เชคเซ‡เชตเซ€ เชงเชพเชฐเชฃเชพ เช เชตเซเชฏเชตเชนเชพเชฐเชฎเชพเช‚ IM เชจเซ€ เชฒเชพเช—เซ เชชเชกเชคเซ€ เชจเซ‹เช‚เชงเชชเชพเชคเซเชฐ เชฎเชฐเซเชฏเชพเชฆเชพ เช›เซ‡. เชชเชฐเช‚เชคเซ เชœเซ‡เชŸเชฒเชพ เชตเชงเซ เชตเชฟเช•เชพเชธเช•เชฐเซเชคเชพเช“ เชคเชฎเชพเชฎ เชชเซเชฐเช•เชพเชฐเชจเชพ NAT-เชŸเซเชฐเชพเชตเชฐเซเชธเชฒ เช•เซเชฐเซ‰เชšเชจเซ‹ เช…เชฎเชฒ เช•เชฐเชถเซ‡, เชคเซ‡เชŸเชฒเชพ เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏ เชธเซเชงเซ€ เช†เชชเชฃเซ‡ IPv4 เชˆเชจเซเชŸเชฐเชจเซ‡เชŸ เชชเชฐ เชฐเชนเซ€เชถเซเช‚, เชœเซ‡เชฎเชพเช‚ เชฎเชจเชธเซเชตเซ€ เช•เซ‹เชฎเซเชชเซเชฏเซเชŸเชฐเซ‹ เชตเชšเซเชšเซ‡ เชธเช‚เชšเชพเชฐเชจเซ€ เชจเชฟเชฐเชพเชถเชพเชœเชจเช• เชธเช‚เชญเชพเชตเชจเชพ เช›เซ‡. เชคเชฎเซ‡ เช•เซเชฏเชพเช‚ เชธเซเชงเซ€ เช˜เชฐเซ‡ เช…เชจเซ‡ เช•เชพเชฎ เชชเชฐ IPv6 เชจเชพ เช…เชญเชพเชตเชจเซ‡ เชธเชนเชจ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹?

เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชซเซเชฐเซ‡เชจเซเชก-เชŸเซ-เชซเซเชฐเซ‡เชจเซเชก เชจเซ‡เชŸเชตเชฐเซเช• เชนเชถเซ‡: เชคเชฎเชพเชฎ เชธเช‚เชญเชตเชฟเชค เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเซเชธ เช…เช—เชพเช‰เชฅเซ€ เชœเชพเชฃเซ€เชคเชพ เชนเซ‹เชตเชพ เชœเซ‹เชˆเช. เชธเซŒเชชเซเชฐเชฅเชฎ, เช† เชฌเชงเซเช‚ เช–เซ‚เชฌ เชœ เชธเชฐเชณ เชฌเชจเชพเชตเซ‡ เช›เซ‡: เช…เชฎเซ‡ เช…เชฎเชพเชฐเซ€ เชœเชพเชคเชจเซ‡ เชชเชฐเชฟเชšเชฏ เช†เชชเซเชฏเซ‹, เชจเชพเชฎ/เช•เซ€ เชถเซ‹เชงเซ€ เช•เซ‡ เชจ เชฎเชณเซ€, เชกเชฟเชธเซเช•เชจเซ‡เช•เซเชŸ เช•เชฐเซเชฏเซเช‚ เช…เชฅเชตเชพ เช•เชพเชฎ เช•เชฐเชตเชพเชจเซเช‚ เชšเชพเชฒเซ เชฐเชพเช–เซเชฏเซเช‚, เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเชจเซ‡ เชœเชพเชฃเซ€เชจเซ‡. เชฌเซ€เชœเซเช‚, เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡, เชคเซ‡ เชธเซเชฐเช•เซเชทเชฟเชค เช›เซ‡ เช…เชจเซ‡ เช˜เชฃเชพ เชนเซเชฎเชฒเชพเช“เชจเซ‡ เชฆเซ‚เชฐ เช•เชฐเซ‡ เช›เซ‡.

IM เช‡เชจเซเชŸเชฐเชซเซ‡เชธ เช•เซเชฒเชพเชธเชฟเช• เชธเซ‹เชฒเซเชฏเซเชถเชจเซเชธเชจเซ€ เชจเชœเซ€เช• เชนเชถเซ‡ เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ, เชœเซ‡ เชฎเชจเซ‡ เชคเซ‡เชฎเชจเชพ เชฎเชฟเชจเชฟเชฎเชฒเชฟเชเชฎ เช…เชจเซ‡ เชฏเซเชจเชฟเช•เซเชธ-เชตเซ‡ เชซเชฟเชฒเชธเซ‚เชซเซ€ เชฎเชพเชŸเซ‡ เช–เชฐเซ‡เช–เชฐ เช—เชฎเซ‡ เช›เซ‡. IM เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎ เชฆเชฐเซ‡เช• เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐ เชฎเชพเชŸเซ‡ เชคเซเชฐเชฃ เชฏเซเชจเชฟเช•เซเชธ เชกเซ‹เชฎเซ‡เชจ เชธเซ‹เช•เซ‡เชŸเซเชธ เชธเชพเชฅเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชฌเชจเชพเชตเซ‡ เช›เซ‡:

  • เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเชจเซ‡ เชฎเซ‹เช•เชฒเชตเชพเชฎเชพเช‚ เช†เชตเซ‡เชฒเชพ เชธเช‚เชฆเซ‡เชถเชพเช“ เชคเซ‡เชฎเชพเช‚ เชฐเซ‡เช•เซ‹เชฐเซเชก เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡;
  • เช†เช‰เชŸ - เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐ เชคเชฐเชซเชฅเซ€ เชฎเชณเซ‡เชฒเชพ เชธเช‚เชฆเซ‡เชถเชพเช“ เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชตเชพเช‚เชšเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡;
  • เชฐเชพเชœเซเชฏ - เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชตเชพเช‚เชšเซ€เชจเซ‡, เช…เชฎเซ‡ เชถเซ‹เชงเซ€ เช•เชพเชขเซ€เช เช›เซ€เช เช•เซ‡ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐ เชนเชพเชฒเชฎเชพเช‚ เชœเซ‹เชกเชพเชฏเซ‡เชฒ เช›เซ‡ เช•เซ‡ เช•เซ‡เชฎ, เช•เชจเซ‡เช•เซเชถเชจ เชธเชฐเชจเชพเชฎเซเช‚/เชชเซ‹เชฐเซเชŸ.

เชตเชงเซเชฎเชพเช‚, เชเช• เช•เซ‹เชจ เชธเซ‹เช•เซ‡เชŸ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชนเซ‹เชธเซเชŸ เชชเซ‹เชฐเซเชŸ เชฒเช–เซ€เชจเซ‡ เชœเซ‡เชฎเชพเช‚ เช†เชชเชฃเซ‡ เชฐเชฟเชฎเซ‹เชŸ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐ เชธเชพเชฅเซ‡ เช•เชจเซ‡เช•เซเชถเชจ เชถเชฐเซ‚ เช•เชฐเซ€เช เช›เซ€เช.

|-- alice
|   |-- in
|   |-- out
|   `-- state
|-- bob
|   |-- in
|   |-- out
|   `-- state
`- conn

เช† เช…เชญเชฟเช—เชฎ เชคเชฎเชจเซ‡ IM เชŸเซเชฐเชพเชจเซเชธเชชเซ‹เชฐเซเชŸ เช…เชจเซ‡ เชฏเซเชเชฐ เช‡เชจเซเชŸเชฐเชซเซ‡เชธเชจเชพ เชธเซเชตเชคเช‚เชคเซเชฐ เช…เชฎเชฒเซ€เช•เชฐเชฃเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เชฎเชฟเชคเซเชฐ เชจเชฅเซ€, เชคเชฎเซ‡ เชฆเชฐเซ‡เช•เชจเซ‡ เช–เซเชถ เช•เชฐเซ€ เชถเช•เชคเชพ เชจเชฅเซ€. เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ tmux เช…เชจเซ‡ / เช…เชฅเชตเชพ เชฎเชฒเซเชŸเชฟเชŸเซ‡เชฒ, เชคเชฎเซ‡ เชธเชฟเชจเซเชŸเซ‡เช•เซเชธ เชนเชพเช‡เชฒเชพเช‡เชŸเชฟเช‚เช— เชธเชพเชฅเซ‡ เชฎเชฒเซเชŸเชฟ-เชตเชฟเชจเซเชกเซ‹ เช‡เชจเซเชŸเชฐเชซเซ‡เชธ เชฎเซ‡เชณเชตเซ€ เชถเช•เซ‹ เช›เซ‹. เช…เชจเซ‡ เชฎเชฆเชฆ เชธเชพเชฅเซ‡ rlwrap เชคเชฎเซ‡ GNU เชฐเซ€เชกเชฒเชพเช‡เชจ-เชธเซเชธเช‚เช—เชค เชธเช‚เชฆเซ‡เชถ เช‡เชจเชชเซเชŸ เชฒเชพเช‡เชจ เชฎเซ‡เชณเชตเซ€ เชถเช•เซ‹ เช›เซ‹.

เชนเช•เซ€เช•เชคเชฎเชพเช‚, เชธเช•เชฒเซ‡เชธ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ FIFO เชซเชพเช‡เชฒเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡. เช…เช‚เช—เชค เชฐเซ€เชคเซ‡, เชนเซเช‚ เชธเชฎเชœเซ€ เชถเช•เชคเซ‹ เชจเชฅเซ€ เช•เซ‡ เชธเชฎเชฐเซเชชเชฟเชค เชฅเซเชฐเซ‡เชกเซ‹เชฎเชพเช‚เชฅเซ€ เชนเชพเชฅเชฅเซ€ เชฒเช–เซ‡เชฒเซ€ เชชเซƒเชทเซเช เชญเซ‚เชฎเชฟ เชตเชฟเชจเชพ เชเชธเชฟเชจเซเชธเชฟเชฏเซ‹เชฎเชพเช‚ เชธเซเชชเชฐเซเชงเชพเชคเซเชฎเช• เชฐเซ€เชคเซ‡ เชซเชพเช‡เชฒเซ‹ เชธเชพเชฅเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเชตเซเช‚ (เชนเซเช‚ เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏเชฅเซ€ เช†เชตเซ€ เชตเชธเซเชคเซเช“ เชฎเชพเชŸเซ‡ เชญเชพเชทเชพเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเช‚ เช›เซเช‚. Go). เชคเซ‡เชฅเซ€, เชฎเซ‡เช‚ เชฏเซเชจเชฟเช•เซเชธ เชกเซ‹เชฎเซ‡เชจ เชธเซ‹เช•เซ‡เชŸเซเชธ เชธเชพเชฅเซ‡ เช•เชฐเชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚. เช•เชฎเชจเชธเซ€เชฌเซ‡, เช† เช‡เช•เซ‹ 2001:470:dead::babe 6666 > conn เช•เชฐเชตเชพเชจเซเช‚ เช…เชถเช•เซเชฏ เชฌเชจเชพเชตเซ‡ เช›เซ‡. เชฎเซ‡เช‚ เช† เชธเชฎเชธเซเชฏเชพเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชนเชฒ เช•เชฐเซ€ เชธเซ‹เช•เซ‡เชŸ: echo 2001:470:dead::bebe 6666 | socat - UNIX-CONNECT:conn, socat READLINE UNIX-Connect:alice/in.

เชฎเซ‚เชณ เช…เชธเซเชฐเช•เซเชทเชฟเชค เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ

TCP เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชชเชฐเชฟเชตเชนเชจ เชคเชฐเซ€เช•เซ‡ เชฅเชพเชฏ เช›เซ‡: เชคเซ‡ เชกเชฟเชฒเชฟเชตเชฐเซ€ เช…เชจเซ‡ เชคเซ‡เชจเชพ เช“เชฐเซเชกเชฐเชจเซ€ เช–เชพเชคเชฐเซ€ เช†เชชเซ‡ เช›เซ‡. UDP เชฌเชพเช‚เชฏเชงเชฐเซ€ เช†เชชเชคเซเช‚ เชจเชฅเซ€ (เชœเซ‡ เชธเช‚เช•เซ‡เชคเชฒเชฟเชชเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เชคเซเชฏเชพเชฐเซ‡ เช‰เชชเชฏเซ‹เช—เซ€ เชฅเชถเซ‡), เชชเชฐเช‚เชคเซ เชธเชฎเชฐเซเชฅเชจ เช†เชชเซ‡ เช›เซ‡ SCTP เชชเชพเชฏเชฅเซ‹เชจ เชฌเซ‹เช•เซเชธเชฎเชพเช‚เชฅเซ€ เชฌเชนเชพเชฐ เช†เชตเชคเซเช‚ เชจเชฅเซ€.

เช•เชฎเชจเชธเซ€เชฌเซ‡, TCP เชฎเชพเช‚ เชธเช‚เชฆเซ‡เชถเชจเซ‹ เช•เซ‹เชˆ เช–เซเชฏเชพเชฒ เชจเชฅเซ€, เชซเช•เซเชค เชฌเชพเชˆเชŸเชจเซ‹ เชชเซเชฐเชตเชพเชน เช›เซ‡. เชคเซ‡เชฅเซ€, เชธเช‚เชฆเซ‡เชถเชพเช“ เชฎเชพเชŸเซ‡ เชเช• เชซเซ‹เชฐเซเชฎเซ‡เชŸ เชธเชพเชฅเซ‡ เช†เชตเชตเซเช‚ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡ เชœเซ‡เชฅเซ€ เชคเซ‡เช“ เช† เชฅเซเชฐเซ‡เชกเชฎเชพเช‚ เชเช•เชฌเซ€เชœเชพ เชธเชพเชฅเซ‡ เชถเซ‡เชฐ เช•เชฐเซ€ เชถเช•เชพเชฏ. เช…เชฎเซ‡ เชฒเชพเช‡เชจ เชซเซ€เชก เช…เช•เซเชทเชฐเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชธเช‚เชฎเชค เชฅเชˆ เชถเช•เซ€เช เช›เซ€เช. เชถเชฐเซ‚เช†เชค เช•เชฐเชจเชพเชฐเชพเช“ เชฎเชพเชŸเซ‡ เชคเซ‡ เชธเชพเชฐเซเช‚ เช›เซ‡, เชชเชฐเช‚เชคเซ เชเช•เชตเชพเชฐ เช…เชฎเซ‡ เช…เชฎเชพเชฐเชพ เชธเช‚เชฆเซ‡เชถเชพเช“เชจเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ€ เชฆเชˆเช, เช† เช…เช•เซเชทเชฐ เชธเชพเช‡เชซเชฐ เชŸเซ‡เช•เซเชธเซเชŸเชฎเชพเช‚ เช—เชฎเซ‡ เชคเซเชฏเชพเช‚ เชฆเซ‡เช–เชพเชˆ เชถเช•เซ‡ เช›เซ‡. เชจเซ‡เชŸเชตเชฐเซเช•เซเชธเชฎเชพเช‚, เชคเซ‡เชฅเซ€, เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เชคเซ‡ เช›เซ‡ เชœเซ‡ เชชเซเชฐเชฅเชฎ เชฌเชพเชˆเชŸเชฎเชพเช‚ เชธเช‚เชฆเซ‡เชถเชจเซ€ เชฒเช‚เชฌเชพเชˆ เชฎเซ‹เช•เชฒเซ‡ เช›เซ‡. เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชฌเซ‹เช•เซเชธเชจเซ€ เชฌเชนเชพเชฐ เชชเชพเชฏเชฅเซ‹เชจเชฎเชพเช‚ xdrlib เช›เซ‡, เชœเซ‡ เชคเชฎเชจเซ‡ เชธเชฎเชพเชจ เชซเซ‹เชฐเซเชฎเซ‡เชŸ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. เชเช•เซเชธเชกเซ€เช†เชฐ.

เช…เชฎเซ‡ TCP เชตเชพเช‚เชšเชจ เชธเชพเชฅเซ‡ เชฏเซ‹เช—เซเชฏ เชฐเซ€เชคเซ‡ เช…เชจเซ‡ เช…เชธเชฐเช•เชพเชฐเช• เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเซ€เชถเซเช‚ เชจเชนเซ€เช‚ - เช…เชฎเซ‡ เช•เซ‹เชกเชจเซ‡ เชธเชฐเชณ เชฌเชจเชพเชตเซ€เชถเซเช‚. เช…เชฎเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เชธเช‚เชฆเซ‡เชถเชจเซ‡ เชกเซ€เช•เซ‹เชก เชจ เช•เชฐเซ€เช เชคเซเชฏเชพเช‚ เชธเซเชงเซ€ เช…เชฎเซ‡ เชธเซ‹เช•เซ‡เชŸเชฎเชพเช‚เชฅเซ€ เชกเซ‡เชŸเชพเชจเซ‡ เช…เชจเช‚เชค เชฒเซ‚เชชเชฎเชพเช‚ เชตเชพเช‚เชšเซ€เช เช›เซ€เช. XML เชธเชพเชฅเซ‡ JSON เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช† เช…เชญเชฟเช—เชฎ เชฎเชพเชŸเซ‡ เชซเซ‹เชฐเซเชฎเซ‡เชŸ เชคเชฐเซ€เช•เซ‡ เชชเชฃ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡. เชชเชฐเช‚เชคเซ เชœเซเชฏเชพเชฐเซ‡ เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเซ€ เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เชกเซ‡เชŸเชพ เชชเชฐ เชนเชธเซเชคเชพเช•เซเชทเชฐเชฟเชค เช…เชจเซ‡ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เช•เชฐเชตเซเช‚ เชชเชกเชถเซ‡ - เช…เชจเซ‡ เช† เชฎเชพเชŸเซ‡ เช‘เชฌเซเชœเซ‡เช•เซเชŸเซเชธเชจเซ€ เชฌเชพเชˆเชŸ-เชฌเชฆ-เชฌเชพเชˆเชŸ เชธเชฎเชพเชจ เชฐเชœเซ‚เช†เชคเชจเซ€ เชœเชฐเซ‚เชฐ เชชเชกเชถเซ‡, เชœเซ‡ JSON/XML เชชเซเชฐเชฆเชพเชจ เช•เชฐเชคเซเช‚ เชจเชฅเซ€ (เชกเชฎเซเชช เชชเชฐเชฟเชฃเชพเชฎเซ‹ เช…เชฒเช—-เช…เชฒเช— เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡).

XDR เช† เช•เชพเชฐเซเชฏ เชฎเชพเชŸเซ‡ เชฏเซ‹เช—เซเชฏ เช›เซ‡, เชœเซ‹ เช•เซ‡ เชนเซเช‚ DER เชเชจเซเช•เซ‹เชกเชฟเช‚เช— เชธเชพเชฅเซ‡ ASN.1 เชชเชธเช‚เชฆ เช•เชฐเซเช‚ เช›เซเช‚ เช…เชจเซ‡ PyDERASN เชชเซเชธเซเชคเช•เชพเชฒเชฏ, เช•เชพเชฐเชฃ เช•เซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เช‰เชšเซเชš-เชธเซเชคเชฐเชจเซ€ เชตเชธเซเชคเซเช“ เชนเชถเซ‡ เชœเซ‡เชจเซ€ เชธเชพเชฅเซ‡ เชคเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช˜เชฃเซ€เชตเชพเชฐ เชตเชงเซ เชธเซเช–เชฆ เช…เชจเซ‡ เช…เชจเซเช•เซ‚เชณ เชนเซ‹เชฏ เช›เซ‡. เชธเซเช•เซ€เชฎเชฒเซ‡เชธเชฅเซ€ เชตเชฟเชชเชฐเซ€เชค เชฌเซ‡เชจเช•เซ‹เชก, เชฎเซ‡เชธเซ‡เชœเชชเซ‡เช• เช…เชฅเชตเชพ CBOR, 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โ”‚ โ””โ”€โ”€โ”ฌโ”˜โ”€โ”€โ”˜ โ”€โ”€ IdA) โ”‚ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”‚ โ”‚ โ”‚ 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(","))

เชคเชฎเชพเชฐเซเช‚ เชชเซ‹เชคเชพเชจเซเช‚ เชจเชพเชฎ เชธเซ‡เชŸ เช•เชฐเซ‹ (--เช…เชฎเชพเชฐเซเช‚-เชจเชพเชฎ เชเชฒเชฟเชธ). เชฌเชงเชพ เช…เชชเซ‡เช•เซเชทเชฟเชค เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเซเชธเชจเซ‡ เช…เชฒเซเชชเชตเชฟเชฐเชพเชฎ เชฆเซเชตเชพเชฐเชพ เช…เชฒเช— เช•เชฐเซ€เชจเซ‡ เชธเซ‚เชšเชฟเชฌเชฆเซเชง เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ (โ€”เชคเซ‡เชฎเชจเชพ-เชจเชพเชฎ เชฌเซ‹เชฌ, เช‡เชต). เชฆเชฐเซ‡เช• เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเซเชธ เชฎเชพเชŸเซ‡, เชฏเซเชจเชฟเช•เซเชธ เชธเซ‹เช•เซ‡เชŸเซเชธ เชธเชพเชฅเซ‡เชจเซ€ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชคเซ‡เชฎเชœ เชฆเชฐเซ‡เช• เช‡เชจ, เช†เช‰เชŸ, เชธเซเชŸเซ‡เชŸ เชฎเชพเชŸเซ‡ เช•เซ‹เชฐเซ‹เชŸเซ€เชจ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡:

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_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 เช•เชคเชพเชฐเซ‹เชฎเชพเช‚ เชฎเซ‹เช•เชฒเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชœเซ‡เชฎเชพเช‚เชฅเซ€ เชกเซ‡เชŸเชพ เช†เช‰เชŸ เชธเซ‹เช•เซ‡เชŸ เชชเชฐ เชฒเช–เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡:

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()

เชธเซเชŸเซ‡เชŸ เชธเซ‹เช•เซ‡เชŸเชฎเชพเช‚เชฅเซ€ เชตเชพเช‚เชšเชคเซ€ เชตเช–เชคเซ‡, เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎ 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()

เช•เซ‹เชจ เชธเซ‹เช•เซ‡เชŸ เชชเชฐ เชธเชฐเชจเชพเชฎเซเช‚ เชฒเช–เชคเซ€ เชตเช–เชคเซ‡, เช•เชจเซ‡เช•เซเชถเชจ "เชชเซเชฐเชพเชฐเช‚เชญเชฟเช•" เช•เชพเชฐเซเชฏ เชถเชฐเซ‚ เชฅเชพเชฏ เช›เซ‡:

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() เช•เซ‰เชฒ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชชเชฐเชฎเชพเชฃเซ เชฐเซ€เชคเซ‡ เชชเซเชฐเชพเชชเซเชค เช•เชฐเซ€เชถเซเช‚. เช…เชฎเซ‡ เชคเชชเชพเชธเซ€เช เช›เซ€เช เช•เซ‡ เช…เชฎเชจเซ‡ เชนเซ‡เชจเซเชกเชถเซ‡เช• เชธเช‚เชฆเซ‡เชถ เชฎเชณเซเชฏเซ‹ เช›เซ‡.

 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 เช•เชคเชพเชฐ เชธเช‚เชฆเซ‡เชถเชจเชพ เชŸเซ‡เช•เซเชธเซเชŸ เชธเชพเชฅเซ‡ เชชเชพเชฏเชฅเซ‹เชจ เชธเซเชŸเซเชฐเซ€เช‚เช— เชงเชฐเชพเชตเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชคเซ‡เชฎเชพเช‚ None เชจเซเช‚ เชตเชฟเชถเซ‡เชท เชฎเซ‚เชฒเซเชฏ เช›เซ‡ เชœเซ‡ msg_sender coroutine เชจเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพเชจเซเช‚ เชฌเช‚เชง เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชธเช‚เช•เซ‡เชค เช†เชชเซ‡ เช›เซ‡ เชœเซ‡เชฅเซ€ เชคเซ‡ เชฒเซ‡เช—เชธเซ€ 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 เช†เช‰เชŸเช—เซ‹เช‡เช‚เช— เชธเช‚เชฆเซ‡เชถเชพเช“ เชธเซเชตเซ€เช•เชพเชฐเซ‡ เช›เซ‡ (เชเช• เช‡เชจ เชธเซ‹เช•เซ‡เชŸเชฎเชพเช‚เชฅเซ€ เช•เชคเชพเชฐเชฎเชพเช‚), เชคเซ‡เชฎเชจเซ‡ 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 coroutine (OUT_QUEUES เช•เชคเชพเชฐเชฎเชพเช‚ None เชฎเซ‹เช•เชฒเซ€เชจเซ‡) เชฌเช‚เชง เช•เชฐเซ€เช เช›เซ€เช.

 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 เชธเชฐเซเชตเชฐ เชถเชฐเซ‚ เช•เชฐเซ€เช เช›เซ€เช. เชฆเชฐเซ‡เช• เชธเซเชฅเชพเชชเชฟเชค เช•เชจเซ‡เช•เซเชถเชจ เชฎเชพเชŸเซ‡, เชคเซ‡ เชชเซเชฐเชคเชฟเชญเชพเชต เช†เชชเชจเชพเชฐ เช•เซ‹เชฐเซ‹เชŸเซ€เชจ เชฌเชจเชพเชตเซ‡ เช›เซ‡.

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()

เชชเซเชฐเชคเชฟเชธเชพเชฆ เช†เชชเชจเชพเชฐ เชถเชฐเซ‚เช†เชคเช•เชฐเซเชคเชพ เชœเซ‡เชตเซ‹ เชœ เช›เซ‡ เช…เชจเซ‡ เชฌเชงเซ€ เชœ เช•เซเชฐเชฟเชฏเชพเช“เชจเซ‡ เชชเซเชฐเชคเชฟเชฌเชฟเช‚เชฌเชฟเชค เช•เชฐเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชธเชฐเชณเชคเชพ เชฎเชพเชŸเซ‡, เชธเช‚เชฆเซ‡เชถเชพเช“ เชตเชพเช‚เชšเชตเชพเชจเซเช‚ เช…เชจเช‚เชค เชฒเซ‚เชช เชคเชฐเชค เชœ เชถเชฐเซ‚ เชฅเชพเชฏ เช›เซ‡. เชนเชพเชฒเชฎเชพเช‚, เชนเซ‡เชจเซเชกเชถเซ‡เช• เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เชฆเชฐเซ‡เช• เชฌเชพเชœเซเชฅเซ€ เชเช• เชธเช‚เชฆเซ‡เชถ เชฎเซ‹เช•เชฒเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชญเชตเชฟเชทเซเชฏเชฎเชพเช‚ เช•เชจเซ‡เช•เซเชถเชจ เช†เชฐเช‚เชญเช•เชฐเซเชคเชพ เชคเชฐเชซเชฅเซ€ เชฌเซ‡ เชนเชถเซ‡, เชœเซ‡เชจเชพ เชชเช›เซ€ เชคเชฐเชค เชœ เชŸเซ‡เช•เซเชธเซเชŸ เชธเช‚เชฆเซ‡เชถเชพ เชฎเซ‹เช•เชฒเซ€ เชถเช•เชพเชฏ เช›เซ‡.

  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()

เชธเซเชฐเช•เซเชทเชฟเชค เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ

เช…เชฎเชพเชฐเชพ เชธเช‚เชšเชพเชฐเชจเซ‡ เชธเซเชฐเช•เซเชทเชฟเชค เช•เชฐเชตเชพเชจเซ‹ เช† เชธเชฎเชฏ เช›เซ‡. เชธเซเชฐเช•เซเชทเชพเชจเซ‹ เช…เชฎเชพเชฐเซ‹ เช…เชฐเซเชฅ เชถเซเช‚ เช›เซ‡ เช…เชจเซ‡ เช…เชฎเชจเซ‡ เชถเซเช‚ เชœเซ‹เชˆเช เช›เซ‡:

  • เชชเซเชฐเชธเชพเชฐเชฟเชค เชธเช‚เชฆเซ‡เชถเชพเช“เชจเซ€ เช—เซเชชเซเชคเชคเชพ;
  • เชชเซเชฐเชธเชพเชฐเชฟเชค เชธเช‚เชฆเซ‡เชถเชพเช“เชจเซ€ เช…เชงเชฟเช•เซƒเชคเชคเชพ เช…เชจเซ‡ เช…เช–เช‚เชกเชฟเชคเชคเชพ - เชคเซ‡เชฎเชจเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชถเซ‹เชงเชตเชพเชฎเชพเช‚ เช†เชตเชถเซเชฏเช• เช›เซ‡;
  • เชฐเซ€เชชเซเชฒเซ‡ เชนเซเชฎเชฒเชพ เชธเชพเชฎเซ‡ เชฐเช•เซเชทเชฃ - เช—เซเชฎ เชฅเชฏเซ‡เชฒ เช…เชฅเชตเชพ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค เชธเช‚เชฆเซ‡เชถเชพเช“เชจเซ€ เชนเช•เซ€เช•เชค เชถเซ‹เชงเชตเซ€ เช†เชตเชถเซเชฏเช• เช›เซ‡ (เช…เชจเซ‡ เช…เชฎเซ‡ เช•เชจเซ‡เช•เซเชถเชจ เชธเชฎเชพเชชเซเชค เช•เชฐเชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซ€เช เช›เซ€เช);
  • เชชเซ‚เชฐเซเชต-เชฆเชพเช–เชฒ เช•เชฐเซ‡เชฒ เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเซเชธเชจเซ€ เช“เชณเช– เช…เชจเซ‡ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ - เช…เชฎเซ‡ เชชเชนเซ‡เชฒเชพเชฅเซ€ เชœ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚ เช›เซ‡ เช•เซ‡ เช…เชฎเซ‡ เชฎเชฟเชคเซเชฐ-เชฅเซ€-เชฎเชฟเชคเซเชฐ เชจเซ‡เชŸเชตเชฐเซเช• เชฌเชจเชพเชตเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช. เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เชชเช›เซ€ เชœ เช†เชชเชฃเซ‡ เชธเชฎเชœเซ€ เชถเช•เซ€เชถเซเช‚ เช•เซ‡ เช†เชชเชฃเซ‡ เช•เซ‹เชจเซ€ เชธเชพเชฅเซ‡ เชตเชพเชคเชšเซ€เชค เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช;
  • เชชเซเชฐเชพเชชเซเชฏเชคเชพ เชธเช‚เชชเซ‚เชฐเซเชฃ เชซเซ‹เชฐเชตเชฐเซเชก เช—เซเชชเซเชคเชคเชพ เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€เช (PFS) - เช…เชฎเชพเชฐเซ€ เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏเชฅเซ€ เชšเชพเชฒเชคเซ€ เชธเชพเชˆเชจเชฟเช‚เช— เช•เซ€ เชธเชพเชฅเซ‡ เชšเซ‡เชกเชพ เช•เชฐเชตเชพเชฅเซ€ เช…เช—เชพเช‰เชจเชพ เชคเชฎเชพเชฎ เชชเชคเซเชฐเชตเซเชฏเชตเชนเชพเชฐ เชตเชพเช‚เชšเชตเชพเชจเซ€ เช•เซเชทเชฎเชคเชพ เชจ เชนเซ‹เชตเซ€ เชœเซ‹เชˆเช. เชฐเซ‡เช•เซ‹เชฐเซเชกเชฟเช‚เช— เช…เชŸเช•เชพเชตเชพเชฏเซ‡เชฒ เชŸเซเชฐเชพเชซเชฟเช• เชจเช•เชพเชฎเซเช‚ เชฌเชจเซ€ เชœเชพเชฏ เช›เซ‡;
  • เชฎเชพเชคเซเชฐ เชเช• TCP เชธเชคเซเชฐเชฎเชพเช‚ เชธเช‚เชฆเซ‡เชถเชพเช“เชจเซ€ เชฎเชพเชจเซเชฏเชคเชพ/เชฎเชพเชจเซเชฏเชคเชพ (เชชเชฐเชฟเชตเชนเชจ เช…เชจเซ‡ เชนเซ‡เชจเซเชกเชถเซ‡เช•). เชฌเซ€เชœเชพ เชธเชคเซเชฐเชฎเชพเช‚เชฅเซ€ เชฏเซ‹เช—เซเชฏ เชฐเซ€เชคเซ‡ เชนเชธเซเชคเชพเช•เซเชทเชฐเชฟเชค/เชชเซเชฐเชฎเชพเชฃเชฟเชค เชธเช‚เชฆเซ‡เชถเชพเช“ เชฆเชพเช–เชฒ เช•เชฐเชตเชพ (เชธเชฎเชพเชจ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐ เชธเชพเชฅเซ‡ เชชเชฃ) เชถเช•เซเชฏ เชจ เชนเซ‹เชตเชพ เชœเซ‹เชˆเช;
  • เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชจเชฟเชฐเซ€เช•เซเชทเช•เซ‡ เช•เซเชฏเชพเช‚ เชคเซ‹ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เช“เชณเช–เช•เชฐเซเชคเชพเช“, เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏเชฅเซ€ เชชเซเชฐเชธเชพเชฐเชฟเชค เชœเชพเชนเซ‡เชฐ เช•เซ€, เช…เชฅเชตเชพ เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชนเซ‡เชถ เชœเซ‹เชตเซ€ เชœเซ‹เชˆเช เชจเชนเซ€เช‚. เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชจเชฟเชฐเซ€เช•เซเชทเช• เชคเชฐเชซเชฅเซ€ เชšเซ‹เช•เซเช•เชธ เช…เชจเชพเชฎเซ€.

เช†เชถเซเชšเชฐเซเชฏเชœเชจเช• เชฐเซ€เชคเซ‡, เชฒเช—เชญเช— เชฆเชฐเซ‡เช• เชœเชฃ เช•เซ‹เชˆเชชเชฃ เชนเซ‡เชจเซเชกเชถเซ‡เช• เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชฎเชพเช‚ เช† เชจเซเชฏเซ‚เชจเชคเชฎ เชฐเชพเช–เชตเชพ เชฎเชพเช‚เช—เซ‡ เช›เซ‡, เช…เชจเซ‡ เช‰เชชเชฐเซ‹เช•เซเชคเชฎเชพเช‚เชฅเซ€ เชฌเชนเซ เช“เช›เชพ "เชตเชคเชจ" เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เชฎเชพเชŸเซ‡ เช†เช–เชฐเซ‡ เชฎเชณเซเชฏเชพ เช›เซ‡. เชนเชตเซ‡ เช…เชฎเซ‡ เช•เช‚เชˆเชชเชฃ เชจเชตเซเช‚ เชถเซ‹เชงเซ€เชถเซเช‚ เชจเชนเซ€เช‚. เชนเซเช‚ เชšเซ‹เช•เซเช•เชธเชชเชฃเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ€ เชญเชฒเชพเชฎเชฃ เช•เชฐเซ€เชถ เช˜เซ‹เช‚เช˜เชพเชŸเชจเซเช‚ เชฎเชพเชณเช–เซเช‚ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡, เชชเชฐเช‚เชคเซ เชšเชพเชฒเซ‹ เช•เช‚เชˆเช• เชธเชฐเชณ เชชเชธเช‚เชฆ เช•เชฐเซ€เช.

เชฌเซ‡ เชธเซŒเชฅเซ€ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เช›เซ‡:

  • TLS - เชฌเช—เซเชธ, เชœเซ…เชฎเซเชฌเซเชธ, เชจเชฌเชณเชพเชˆเช“, เชจเชฌเชณเชพ เชตเชฟเชšเชพเชฐ, เชœเชŸเชฟเชฒเชคเชพ เช…เชจเซ‡ เช–เชพเชฎเซ€เช“เชจเซ‹ เชฒเชพเช‚เชฌเซ‹ เช‡เชคเชฟเชนเชพเชธ เชงเชฐเชพเชตเชคเซ‹ เช–เซ‚เชฌ เชœ เชœเชŸเชฟเชฒ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ (เชœเซ‹ เช•เซ‡, เช†เชจเซ‹ TLS 1.3 เชธเชพเชฅเซ‡ เชฌเชนเซ เช“เช›เซ‹ เชธเช‚เชฌเช‚เชง เช›เซ‡). เชชเชฐเช‚เชคเซ เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชคเชพ เชจเชฅเซ€ เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เชตเชงเซ เชœเชŸเชฟเชฒ เช›เซ‡.
  • IPsec ั เช†เช‡เช•เซ‡เช‡ โ€” เช—เช‚เชญเซ€เชฐ เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเชฟเช• เชธเชฎเชธเซเชฏเชพเช“ เชจเชฅเซ€, เชœเซ‹ เช•เซ‡ เชคเซ‡ เชธเชฐเชณ เชชเชฃ เชจเชฅเซ€. เชœเซ‹ เชคเชฎเซ‡ IKEv1 เช…เชจเซ‡ IKEv2 เชตเชฟเชถเซ‡ เชตเชพเช‚เชšเซ‹ เช›เซ‹, เชคเซ‹ เชคเซ‡เชฎเชจเซ‹ เชธเซเชคเซเชฐเซ‹เชค เช›เซ‡ เชเชธเชŸเซ€เชเชธ, ISO/IEC IS 9798-3 เช…เชจเซ‡ SIGMA (SIGn-and-MAc) เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ - เชเช• เชธเชพเช‚เชœเซ‡ เช…เชฎเชฒ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชชเซ‚เชฐเชคเชพ เชธเชฐเชณ.

STS/ISO เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชจเชพ เชตเชฟเช•เชพเชธเชฎเชพเช‚ เชจเชตเซ€เชจเชคเชฎ เช•เชกเซ€ เชคเชฐเซ€เช•เซ‡ SIGMA เชตเชฟเชถเซ‡ เชถเซเช‚ เชธเชพเชฐเซเช‚ เช›เซ‡? เชคเซ‡ เช…เชฎเชพเชฐเซ€ เชฌเชงเซ€ เช†เชตเชถเซเชฏเช•เชคเชพเช“เชจเซ‡ เชชเซ‚เชฐเซเชฃ เช•เชฐเซ‡ เช›เซ‡ ("เช›เซเชชเชพเชตเชตเชพ" เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐ เช“เชณเช–เช•เชฐเซเชคเชพเช“ เชธเชนเชฟเชค) เช…เชจเซ‡ เชคเซ‡เชฎเชพเช‚ เช•เซ‹เชˆ เชœเชพเชฃเซ€เชคเซ€ เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเชฟเช• เชธเชฎเชธเซเชฏเชพเช“ เชจเชฅเซ€. เชคเซ‡ เชจเซเชฏเซ‚เชจเชคเชฎ เช›เซ‡ - เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เชธเช‚เชฆเซ‡เชถเชฎเชพเช‚เชฅเซ€ เช“เช›เชพเชฎเชพเช‚ เช“เช›เชพ เชเช• เช˜เชŸเช•เชจเซ‡ เชฆเซ‚เชฐ เช•เชฐเชตเชพเชฅเซ€ เชคเซ‡เชจเซ€ เช…เชธเซเชฐเช•เซเชทเชพ เชคเชฐเชซ เชฆเซ‹เชฐเซ€ เชœเชถเซ‡.

เชšเชพเชฒเซ‹ เชธเซŒเชฅเซ€ เชธเชฐเชณ เช˜เชฐเซ‡เชฒเซ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชฅเซ€ SIGMA เชชเชฐ เชœเชˆเช. เช…เชฎเชจเซ‡ เชฐเชธ เช›เซ‡ เชคเซ‡ เชธเซŒเชฅเซ€ เชฎเซ‚เชณเชญเซ‚เชค เช•เชพเชฎเช—เซ€เชฐเซ€ เช›เซ‡ เชฎเซเช–เซเชฏ เช•เชฐเชพเชฐ: เชเช• เช•เชพเชฐเซเชฏ เช•เซ‡ เชœเซ‡ เชฌเช‚เชจเซ‡ เชธเชนเชญเชพเช—เซ€เช“เชจเซ‡ เชธเชฎเชพเชจ เชฎเซ‚เชฒเซเชฏ เช†เช‰เชŸเชชเซเชŸ เช•เชฐเซ‡ เช›เซ‡, เชœเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชธเชชเซเชฐเชฎเชพเชฃ เช•เซ€ เชคเชฐเซ€เช•เซ‡ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡. เชตเชฟเช—เชคเซ‹เชฎเชพเช‚ เช—เชฏเชพ เชตเชฟเชจเชพ: เชฆเชฐเซ‡เช• เชชเช•เซเชทเซ‹ เช•เซเชทเชฃเชฟเช• (เชซเช•เซเชค เชเช• เชธเชคเซเชฐเชฎเชพเช‚ เชตเชชเชฐเชพเชฏเซ‡เชฒ) เช•เซ€ เชœเซ‹เชกเซ€ (เชœเชพเชนเซ‡เชฐ เช…เชจเซ‡ เช–เชพเชจเช—เซ€ เช•เซ€) เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡, เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เชจเซ€ เช†เชชเชฒเซ‡ เช•เชฐเซ‡ เช›เซ‡, เชเช—เซเชฐเซ€เชฎเซ‡เชจเซเชŸ เชซเช‚เช•เซเชถเชจเชจเซ‡ เช•เซ‰เชฒ เช•เชฐเซ‡ เช›เซ‡, เชœเซ‡เชจเชพ เช‡เชจเชชเซเชŸเชฎเชพเช‚ เชคเซ‡เช“ เชคเซ‡เชฎเชจเซ€ เช–เชพเชจเช—เซ€ เช•เซ€ เช…เชจเซ‡ เชœเชพเชนเซ‡เชฐ เชœเชจเชคเชพเชจเซ‡ เชชเชพเชธ เช•เชฐเซ‡ เช›เซ‡. เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเชจเซ€ เชšเชพเชตเซ€.

โ”Œโ”€โ”€โ”€โ”€โ”‚ โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚ โ•‘PrvA(PrvA), โ• โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚ IdB, PubB โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ•‘PrvB, PubB = DHgen()โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”€โ”€โ”€โ” โ•”โ•โ•โ•โ• โ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚ โ•‘Key = DH(PrvA, PubB)โ•‘ <โ”€โ”€โ”€โ•‘ <โ”€โ”€โ”€โ”˜โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ• โ”‚ โ”‚ โ”‚ โ”‚

เช•เซ‹เชˆเชชเชฃ เชฎเชงเซเชฏเชฎเชพเช‚ เช•เซ‚เชฆเซ€ เชถเช•เซ‡ เช›เซ‡ เช…เชจเซ‡ เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เชจเซ‡ เชคเซ‡เชฎเชจเซ€ เชชเซ‹เชคเชพเชจเซ€ เชธเชพเชฅเซ‡ เชฌเชฆเชฒเซ€ เชถเช•เซ‡ เช›เซ‡ - เช† เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชฎเชพเช‚ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเซเชธเชจเซเช‚ เช•เซ‹เชˆ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เชจเชฅเซ€. เชšเชพเชฒเซ‹ เชฒเชพเช‚เชฌเชพ เช—เชพเชณเชพเชจเซ€ เชšเชพเชตเซ€เช“ เชธเชพเชฅเซ‡ เชธเชนเซ€ เช‰เชฎเซ‡เชฐเซ€เช.

โ”Œโ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ” โ”‚PeerAโ”‚ โ”‚PeerBโ”‚ โ””โ”€โ”€โ”ฌโ”˜Aโ”€โ”˜ โ”€โ”€ เชšเชฟเชนเซเชจ(SignPrvA, (PubA)) โ”‚ โ•”โ• โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ””Aign ubA = เชฒเซ‹เชก()โ•‘ โ”‚ โ”‚ โ•‘PrvA, PubA = DHgen() โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• , เชšเชฟเชนเซเชจ (PrvB, (PubB)) โ”‚ โ•”โ•โ•โ•โ””โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”‚ โ•‘SignPrvB, SignPubB = load( )โ•‘ โ”‚ โ”‚ โ•‘PrvB, PubB = DH โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ• โ”€โ”€โ”€โ”€โ” โ•” โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•— โ”‚ โ”‚ โ•‘เชšเช•เชพเชธเซ‹( SignPubB, ...)โ•‘ โ”‚ <โ”€โ”€โ”€โ”˜ โ•‘Key = DH(Pr vA, PubB) โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ• โ”‚ โ”‚ โ”‚

เช†เชตเชพ เชนเชธเซเชคเชพเช•เซเชทเชฐ เช•เชพเชฎ เช•เชฐเชถเซ‡ เชจเชนเซ€เช‚, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เชšเซ‹เช•เซเช•เชธ เชธเชคเซเชฐ เชธเชพเชฅเซ‡ เชœเซ‹เชกเชพเชฏเซ‡เชฒ เชจเชฅเซ€. เช†เชตเชพ เชธเช‚เชฆเซ‡เชถเชพเช“ เช…เชจเซเชฏ เชธเชนเชญเชพเช—เซ€เช“ เชธเชพเชฅเซ‡เชจเชพ เชธเชคเซเชฐเซ‹ เชฎเชพเชŸเซ‡ เชชเชฃ "เชฏเซ‹เช—เซเชฏ" เช›เซ‡. เชธเชฎเช—เซเชฐ เชธเช‚เชฆเชฐเซเชญเซ‡ เชธเชฌเซเชธเซเช•เซเชฐเชพเช‡เชฌ เช•เชฐเชตเซเช‚ เช†เชตเชถเซเชฏเช• เช›เซ‡. เช† เช…เชฎเชจเซ‡ A เชคเชฐเชซเชฅเซ€ เชฌเซ€เชœเซ‹ เชธเช‚เชฆเซ‡เชถ เช‰เชฎเซ‡เชฐเชตเชพเชจเซ€ เชซเชฐเชœ เชชเชพเชกเซ‡ เช›เซ‡.

เชตเชงเซเชฎเชพเช‚, เชธเชนเซ€ เชนเซ‡เช เชณ เชคเชฎเชพเชฐเชพ เชชเซ‹เชคเชพเชจเชพ เช“เชณเช–เช•เชฐเซเชคเชพเชจเซ‡ เช‰เชฎเซ‡เชฐเชตเซเช‚ เชฎเชนเชคเซเชตเชชเซ‚เชฐเซเชฃ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เช…เชจเซเชฏเชฅเชพ เช…เชฎเซ‡ IdXXX เชจเซ‡ เชฌเชฆเชฒเซ€ เชถเช•เซ€เช เช›เซ€เช เช…เชจเซ‡ เช…เชจเซเชฏ เชœเชพเชฃเซ€เชคเชพ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเชจเซ€ เช•เซ€ เชตเชกเซ‡ เชธเช‚เชฆเซ‡เชถ เชชเชฐ เชซเชฐเซ€เชฅเซ€ เชธเชนเซ€ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช. เช…เชŸเช•เชพเชตเชตเชพ เชชเซเชฐเชคเชฟเชฌเชฟเช‚เชฌ เชนเซเชฎเชฒเชพ, เชคเซ‡ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡ เช•เซ‡ เชนเชธเซเชคเชพเช•เซเชทเชฐ เชนเซ‡เช เชณเชจเชพ เชคเชคเซเชตเซ‹ เชคเซ‡เชฎเชจเชพ เช…เชฐเซเชฅ เช…เชจเซเชธเชพเชฐ เชธเซเชชเชทเซเชŸ เชฐเซ€เชคเซ‡ เชตเซเชฏเชพเช–เซเชฏเชพเชฏเชฟเชค เชธเซเชฅเชพเชจเซ‹ เชชเชฐ เชนเซ‹เชฏ: เชœเซ‹ A เชšเชฟเชนเซเชจเซ‹ (PubA, PubB), เชคเซ‹ B เชฆเซเชตเชพเชฐเชพ เชธเชนเซ€ เช•เชฐเชตเซ€ เช†เชตเชถเซเชฏเช• เช›เซ‡ (PubB, PubA). เช† เชถเซเชฐเซ‡เชฃเซ€เชฌเชฆเซเชง เชกเซ‡เชŸเชพเชจเชพ เชฌเช‚เชงเชพเชฐเชฃ เช…เชจเซ‡ เชซเซ‹เชฐเซเชฎเซ‡เชŸเชจเซ‡ เชชเชธเช‚เชฆ เช•เชฐเชตเชพเชจเชพ เชฎเชนเชคเซเชต เชตเชฟเชถเซ‡ เชชเชฃ เชตเชพเชค เช•เชฐเซ‡ เช›เซ‡. เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, ASN.1 DER เชเชจเซเช•เซ‹เชกเชฟเช‚เช—เชฎเชพเช‚ เชธเซ‡เชŸเชจเซ‡ เชธเซ‰เชฐเซเชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡: SET OF(PubA, PubB) SET OF(PubB, PubA) เชธเชฎเชพเชจ เชนเชถเซ‡.

โ”Œโ”€โ”€โ”€โ”€โ”‚ โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - โ• โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚IdB, PubB, เชšเชฟเชนเซเชจ(SignPrvB, (IdB, PubA, PubB)) โ”‚ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚ โ•‘SignPrvB, SignPubB = load()โ•‘ โ”‚ โ”‚ โ•‘PrvB, PubB = DHgen() โ•‘ โ”‚ โ”‚ โ”‚ โ• โ• โ• โ• โ• โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚ เชšเชฟเชนเซเชจ(SignPrvA, (IdA, PubB, PubA)) โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•— โ”‚โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€>โ”‚ โ•‘เชšเช•เชพเชธเซ‹(SignPubB, ...) โ•‘ โ”‚ โ”‚ โ•‘key = dh (prva, PUBB) โ•‘ โ”‚ โ”‚ โ”‚

เชœเซ‹ เช•เซ‡, เช…เชฎเซ‡ เชนเชœเซ€ เชชเชฃ "เชธเชพเชฌเชฟเชค" เชจเชฅเซ€ เช•เชฐเซเชฏเซเช‚ เช•เซ‡ เช…เชฎเซ‡ เช† เชธเชคเซเชฐ เชฎเชพเชŸเซ‡ เชธเชฎเชพเชจ เชถเซ‡เชฐ เช•เชฐเซ‡เชฒเซ€ เช•เซ€ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ€ เช›เซ‡. เชธเซˆเชฆเซเชงเชพเช‚เชคเชฟเช• เชฐเซ€เชคเซ‡, เช…เชฎเซ‡ เช† เชชเช—เชฒเชพ เชตเชฟเชจเชพ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช - เชชเซเชฐเชฅเชฎ เชชเชฐเชฟเชตเชนเชจ เช•เชจเซ‡เช•เซเชถเชจ เช…เชฎเชพเชจเซเชฏ เชนเชถเซ‡, เชชเชฐเช‚เชคเซ เช…เชฎเซ‡ เช‡เชšเซเช›เซ€เช เช›เซ€เช เช•เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชนเซ‡เชจเซเชกเชถเซ‡เช• เชชเซ‚เชฐเซเชฃ เชฅเชพเชฏ, เชคเซเชฏเชพเชฐเซ‡ เช…เชฎเซ‡ เช–เชพเชคเชฐเซ€ เช•เชฐเซ€เชถเซเช‚ เช•เซ‡ เชฌเชงเซเช‚ เช–เชฐเซ‡เช–เชฐ เชธเช‚เชฎเชค เช›เซ‡. เช…เชคเซเชฏเชพเชฐเซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ ISO/IEC IS 9798-3 เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เช›เซ‡.

เช…เชฎเซ‡ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡เชฒเซ€ เช•เซ€ เชชเชฐ เชœ เชธเชนเซ€ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช. เช† เช–เชคเชฐเชจเชพเช• เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชธเช‚เชญเชต เช›เซ‡ เช•เซ‡ เช‰เชชเชฏเซ‹เช—เชฎเชพเช‚ เชฒเซ‡เชตเชพเชคเชพ เชนเชธเซเชคเชพเช•เซเชทเชฐ เช…เชฒเซเช—เซ‹เชฐเชฟเชงเชฎเชฎเชพเช‚ เชฒเซ€เช• เชฅเชˆ เชถเช•เซ‡ เช›เซ‡ (เชฌเชฟเชŸเซเชธ-เชชเซเชฐเชคเชฟ-เชธเชฟเช—เซเชจเซ‡เชšเชฐ เชนเซ‹เชตเชพ เช›เชคเชพเช‚, เชชเชฐเช‚เชคเซ เชนเชœเซ เชชเชฃ เชฒเซ€เช• เชฅเชพเชฏ เช›เซ‡). เชตเซเชฏเซเชคเซเชชเชจเซเชจ เช•เซ€เชจเชพ เชนเซ‡เชถ เชชเชฐ เชธเชนเซ€ เช•เชฐเชตเซ€ เชถเช•เซเชฏ เช›เซ‡, เชชเชฐเช‚เชคเซ เชตเซเชฏเซเชคเซเชชเชจเซเชจ เช•เซ€เชจเชพ เชนเซ‡เชถเชจเซ‡ เชฒเซ€เช• เช•เชฐเชตเซเช‚ เชชเชฃ เชตเซเชฏเซเชคเซเชชเชจเซเชจ เช•เชพเชฐเซเชฏ เชชเชฐเชจเชพ เชฌเซเชฐเซเชŸ-เชซเซ‹เชฐเซเชธ เชนเซเชฎเชฒเชพเชฎเชพเช‚ เชฎเซ‚เชฒเซเชฏเชตเชพเชจ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡. SIGMA MAC เชซเช‚เช•เซเชถเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡ เชœเซ‡ เชชเซเชฐเซ‡เชทเช• ID เชจเซ‡ เชชเซเชฐเชฎเชพเชฃเชฟเชค เช•เชฐเซ‡ เช›เซ‡.

โ”Œโ”€โ”€โ”€โ”€โ”‚ โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚ โ•‘SignPrvA, SignPubA = load()โ•‘ โ”‚ โ”‚ โ•‘Prv()โ•‘ โ”‚ โ”‚ โ•‘ Prv โ•š โ•โ•โ•โ•โ•โ•โ• โ•- โ•โ•โ• โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”‚ โ•‘SignPrvB, SignPubB = load()โ•‘ โ”‚ โ”‚ โ•‘PrvB, PubB = DHgen() โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ• - โ”‚ โ•‘ เช•เซ€ = DH( PrvA, PubB) โ•‘ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€>โ”‚ โ•‘เชšเช•เชพเชธเซ‹(เช•เซ€, IdB) โ•‘ โ”‚ โ”‚ โ•‘เชšเช•เชพเชธเซ‹(SignPubB, ...)โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ• โ•โ• โ”‚ โ”‚

เช‘เชชเซเชŸเชฟเชฎเชพเช‡เชเซ‡เชถเชจ เชคเชฐเซ€เช•เซ‡, เช•เซ‡เชŸเชฒเชพเช• เชคเซ‡เชฎเชจเซ€ เช•เซเชทเชฃเชฟเช• เช•เซ€เชจเซ‹ เชซเชฐเซ€เชฅเซ€ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพ เชฎเชพเช‚เช—เซ‡ เช›เซ‡ (เชœเซ‡ เช…เชฒเชฌเชคเซเชค, PFS เชฎเชพเชŸเซ‡ เช•เชฎเชจเชธเซ€เชฌ เช›เซ‡). เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เช…เชฎเซ‡ เชเช• เช•เซ€ เชœเซ‹เชกเซ€ เชฌเชจเชพเชตเซ€, เช•เชจเซ‡เช•เซเชŸ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซเชฏเซ‹, เชชเชฐเช‚เชคเซ TCP เช‰เชชเชฒเชฌเซเชง เชจเชนเซ‹เชคเซเช‚ เช…เชฅเชตเชพ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชจเซ€ เชฎเชงเซเชฏเชฎเชพเช‚ เช•เซเชฏเชพเช‚เช• เชตเชฟเช•เซเชทเซ‡เชชเชฟเชค เชฅเชฏเซ‹ เชนเชคเซ‹. เชจเชตเซ€ เชœเซ‹เชกเซ€ เชชเชฐ เชตเซเชฏเชฐเซเชฅ เชเชจเซเชŸเซเชฐเซ‹เชชเซ€ เช…เชจเซ‡ เชชเซเชฐเซ‹เชธเซ‡เชธเชฐ เชธเช‚เชธเชพเชงเชจเซ‹เชจเซ‹ เชฌเช—เชพเชก เช•เชฐเชตเซ‹ เชถเชฐเชฎเชœเชจเช• เช›เซ‡. เชคเซ‡เชฅเซ€, เช…เชฎเซ‡ เช•เชนเซ‡เชตเชพเชคเซ€ เช•เซ‚เช•เซ€ เชฐเชœเซ‚ เช•เชฐเซ€เชถเซเช‚ - เชเช• เชธเซเชฏเซเชกเซ‹-เชฐเซ‡เชจเซเชกเชฎ เชฎเซ‚เชฒเซเชฏ เช•เซ‡ เชœเซ‡ เช•เซเชทเชฃเชฟเช• เชœเชพเชนเซ‡เชฐ เช•เซ€เชจเซ‹ เชซเชฐเซ€เชฅเซ€ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เชธเช‚เชญเชตเชฟเชค เชฐเซ‡เชจเซเชกเชฎ เชฐเซ€เชชเซเชฒเซ‡ เชนเซเชฎเชฒเชพเช“ เชธเชพเชฎเซ‡ เชฐเช•เซเชทเชฃ เช•เชฐเชถเซ‡. เช•เซ‚เช•เซ€ เช…เชจเซ‡ เช•เซเชทเชฃเชฟเช• เชœเชพเชนเซ‡เชฐ เช•เซ€ เชตเชšเซเชšเซ‡เชจเชพ เชฌเช‚เชงเชจเชจเซ‡ เช•เชพเชฐเชฃเซ‡, เชตเชฟเชฐเซ‹เชงเซ€ เชชเช•เซเชทเชจเซ€ เชœเชพเชนเซ‡เชฐ เช•เซ€ เชฌเชฟเชจเชœเชฐเซ‚เชฐเซ€ เชคเชฐเซ€เช•เซ‡ เชธเชนเซ€เชฎเชพเช‚เชฅเซ€ เชฆเซ‚เชฐ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡.

โ”Œโ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ” โ”‚PeerAโ”‚ โ”‚PeerBโ”‚ โ””โ”€โ”€โ”ฌโ”˜ Ibโ”€โ”€ เช•เซ‚เช•เซ€เช โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚โ”€โ”€โ”€โ”€โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€>โ”‚ โ•‘SignPrvA, SignPubA = เชฒเซ‹เชก( )โ•‘ โ”‚ โ”‚ โ•‘PrvA, PubA = DHgen() โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ• โ”‚IdB, PubB, CookieB , sign(SignPrvB, (CookieA, CookieB, PubB)), MAC(IdB) โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ• โ•— โ”‚< โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - โ”‚ โ•šโ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚ โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚ เชšเชฟเชนเซเชจ( SignPrvA, (CookieB, CookieA, PubA)), MAC(IdA) โ”‚ โ•‘Key = DH(PrvA, PubB) โ•‘ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€ โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚ โ•‘ เชšเช•เชพเชธเซ‹(เช•เซ€, IdB) โ•‘ โ”‚ โ”‚ โ•‘เชšเช•เชพเชธเซ‹(SignPubB, ...)โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚ โ”‚

เช…เช‚เชคเซ‡, เช…เชฎเซ‡ เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชจเชฟเชฐเซ€เช•เซเชทเช• เชชเชพเชธเซ‡เชฅเซ€ เช…เชฎเชพเชฐเชพ เชตเชพเชคเชšเซ€เชค เชญเชพเช—เซ€เชฆเชพเชฐเซ‹เชจเซ€ เช—เซ‹เชชเชจเซ€เชฏเชคเชพ เชฎเซ‡เชณเชตเชตเชพ เชฎเชพเช‚เช—เซ€เช เช›เซ€เช. เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, SIGMA เช เชชเซเชฐเชฅเชฎ เช•เซเชทเชฃเชฟเช• เช•เซ€เชจเซ€ เช†เชชเชฒเซ‡ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชธเซเชคเชพเชต เชฎเซ‚เช•เซ‡ เช›เซ‡ เช…เชจเซ‡ เชเช• เชธเชพเชฎเชพเชจเซเชฏ เช•เซ€ เชตเชฟเช•เชธเชพเชตเซ‡ เช›เซ‡ เชœเซ‡เชจเชพ เชชเชฐ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เช…เชจเซ‡ เชธเช‚เชฆเซ‡เชถเชพเช“เชจเซ‡ เช“เชณเช–เซ€ เชถเช•เชพเชฏ เช›เซ‡. เชธเชฟเช—เซเชฎเชพ เชฌเซ‡ เชตเชฟเช•เชฒเซเชชเซ‹เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ‡ เช›เซ‡:

  • SIGMA-I - เช†เชฐเช‚เชญเช•เชฐเซเชคเชพเชจเซ‡ เชธเช•เซเชฐเชฟเชฏ เชนเซเชฎเชฒเชพเช“เชฅเซ€, เชชเซเชฐเชคเชฟเชธเชพเชฆเช•เชฐเซเชคเชพเชจเซ‡ เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชนเซเชฎเชฒเชพเช“เชฅเซ€ เชฐเช•เซเชทเชฃ เช†เชชเซ‡ เช›เซ‡: เช†เชฐเช‚เชญเช•เชฐเซเชคเชพ เชชเซเชฐเชคเชฟเชธเชพเชฆ เช†เชชเชจเชพเชฐเชจเซ‡ เชชเซเชฐเชฎเชพเชฃเชฟเชค เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ เชœเซ‹ เช•เช‚เชˆเช• เชฎเซ‡เชณ เช–เชพเชคเซเช‚ เชจเชฅเซ€, เชคเซ‹ เชคเซ‡ เชคเซ‡เชจเซ€ เช“เชณเช– เช†เชชเชคเซเช‚ เชจเชฅเซ€. เชœเซ‹ เชคเซ‡เชจเซ€ เชธเชพเชฅเซ‡ เชธเช•เซเชฐเชฟเชฏ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เชถเชฐเซ‚ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เชคเซ‹ เชชเซเชฐเชคเชฟเชตเชพเชฆเซ€ เชคเซ‡เชจเซ€ เช“เชณเช– เช†เชชเซ‡ เช›เซ‡. เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชจเชฟเชฐเซ€เช•เซเชทเช• เช•เช‚เชˆ เชถเซ€เช–เชคเซ‹ เชจเชฅเซ€;
    เชธเชฟเช—เซเชฎเชพ-เช†เชฐ - เชธเช•เซเชฐเชฟเชฏ เชนเซเชฎเชฒเชพเช“เชฅเซ€ เชชเซเชฐเชคเชฟเชธเชพเชฆ เช†เชชเชจเชพเชฐเชจเซเช‚ เชฐเช•เซเชทเชฃ เช•เชฐเซ‡ เช›เซ‡, เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชฒเซ‹เช•เซ‹เชฅเซ€ เช†เชฐเช‚เชญ เช•เชฐเชจเชพเชฐเชจเซ‡. เชฌเชงเซเช‚ เชฌเชฐเชพเชฌเชฐ เชตเชฟเชฐเซเชฆเซเชง เช›เซ‡, เชชเชฐเช‚เชคเซ เช† เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชฎเชพเช‚ เชšเชพเชฐ เชนเซ‡เชจเซเชกเชถเซ‡เช• เชธเช‚เชฆเซ‡เชถเชพเช“ เชชเชนเซ‡เชฒเชพเชฅเซ€ เชœ เชชเซเชฐเชธเชพเชฐเชฟเชค เชฅเชพเชฏ เช›เซ‡.

    เช…เชฎเซ‡ SIGMA-I เชชเชธเช‚เชฆ เช•เชฐเซ€เช เช›เซ€เช เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เช•เซเชฒเชพเชฏเช‚เชŸ-เชธเชฐเซเชตเชฐ เชชเชฐเชฟเชšเชฟเชค เชตเชธเซเชคเซเช“ เชชเชพเชธเซ‡เชฅเซ€ เช†เชชเชฃเซ‡ เชœเซ‡ เช…เชชเซ‡เช•เซเชทเชพ เชฐเชพเช–เซ€เช เช›เซ€เช เชคเซ‡เชจเชพ เชœเซ‡เชตเซเช‚ เชœ เช›เซ‡: เช•เซเชฒเชพเชฏเช‚เชŸเชจเซ‡ เชฎเชพเชคเซเชฐ เชชเซเชฐเชฎเชพเชฃเชฟเชค เชธเชฐเซเชตเชฐ เชฆเซเชตเชพเชฐเชพ เชœ เช“เชณเช–เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เช…เชจเซ‡ เชฆเชฐเซ‡เช• เชœเชฃ เชธเชฐเซเชตเชฐเชจเซ‡ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เชœเชพเชฃเซ‡ เช›เซ‡. เช‰เชชเชฐเชพเช‚เชค เช“เช›เชพ เชนเซ‡เชจเซเชกเชถเซ‡เช• เชธเช‚เชฆเซ‡เชถเชพเชจเซ‡ เช•เชพเชฐเชฃเซ‡ เชคเซ‡เชจเซ‡ เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเซเช‚ เชธเชฐเชณ เช›เซ‡. เช…เชฎเซ‡ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชฎเชพเช‚ เชœเซ‡ เช‰เชฎเซ‡เชฐเซ€เช เช›เซ€เช เชคเซ‡ เชธเช‚เชฆเซ‡เชถเชจเชพ เชญเชพเช—เชจเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพเชจเซเช‚ เช›เซ‡ เช…เชจเซ‡ เช“เชณเช–เช•เชฐเซเชคเชพ A เชจเซ‡ เช›เซ‡เชฒเซเชฒเชพ เชธเช‚เชฆเซ‡เชถเชจเชพ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸเซ‡เชก เชญเชพเช—เชฎเชพเช‚ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เช•เชฐเชตเชพเชจเซเช‚ เช›เซ‡:

    PubA, CookieA โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚ โ•‘SignPrvA , SignPubA = load()โ•‘ โ”‚ โ”‚ โ•‘PrvA, PubA = DHgen() โ•‘ โ•‚ โ•โ•โ•โ•โ•โ•โ•โ•โ• . โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•— โ”‚<โ”€โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ - โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ”‚ โ”‚ โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•— โ”‚ Enc((IdA, เชšเชฟเชนเซเชจ( SignPrvA, (CookieB, CookieA, PubA)), MAC(IdA))) โ”‚ โ•‘Key = DH(PrvA, PubB) โ•‘ โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚ โ•‘เชšเช•เชพเชธเซ‹(เช•เซ€, IdB) โ•‘ โ”‚ โ”‚ โ•‘เชšเช•เชพเชธเซ‹( SignPubB, ...)โ•‘ โ”‚ โ”‚ โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• โ•โ•โ•โ•โ• โ•โ•โ• โ”‚ โ”‚
    
    • GOST R เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชธเชนเซ€ เชฎเชพเชŸเซ‡ เชฅเชพเชฏ เช›เซ‡ 34.10-2012 256-เชฌเซ€เชŸ เช•เซ€ เชธเชพเชฅเซ‡ เช…เชฒเซเช—เซ‹เชฐเชฟเชงเชฎ.
    • เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€ เชœเชจเชฐเซ‡เชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, 34.10-2012 VKO เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชฅเชพเชฏ เช›เซ‡.
    • CMAC เชจเซ‹ เช‰เชชเชฏเซ‹เช— MAC เชคเชฐเซ€เช•เซ‡ เชฅเชพเชฏ เช›เซ‡. เชคเช•เชจเซ€เช•เซ€ เชฐเซ€เชคเซ‡, เช† GOST R 34.13-2015 เชฎเชพเช‚ เชตเชฐเซเชฃเชตเซ‡เชฒ เชฌเซเชฒเซ‹เช• เชธเชพเช‡เชซเชฐเชจเซ€ เช•เชพเชฎเช—เซ€เชฐเซ€เชจเซ‹ เชเช• เชตเชฟเชถเชฟเชทเซเชŸ เชฎเซ‹เชก เช›เซ‡. เช† เชฎเซ‹เชก เชฎเชพเชŸเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชซเช‚เช•เซเชถเชจ เชคเชฐเซ€เช•เซ‡ - เช–เชกเชฎเชพเช•เชกเซ€ (34.12-2015).
    • เชคเซ‡เชจเซ€ เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เชจเชพ เชนเซ‡เชถเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเชจเชพ เช“เชณเช–เช•เชฐเซเชคเชพ เชคเชฐเซ€เช•เซ‡ เชฅเชพเชฏ เช›เซ‡. เชนเซ‡เชถ เชคเชฐเซ€เช•เซ‡ เชตเชชเชฐเชพเชฏ เช›เซ‡ เชธเซเชŸเซเชฐเชฟเชฌเซ‹เช—-256 (34.11/2012/256 XNUMX เชฌเชฟเชŸเซเชธ).

    เชนเซ‡เชจเซเชกเชถเซ‡เช• เชชเช›เซ€, เช…เชฎเซ‡ เชถเซ‡เชฐ เช•เชฐเซ‡เชฒเซ€ เช•เซ€ เชชเชฐ เชธเช‚เชฎเชค เชฅเชˆเชถเซเช‚. เช…เชฎเซ‡ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชชเชฐเชฟเชตเชนเชจ เชธเช‚เชฆเซ‡เชถเชพเช“เชจเชพ เช…เชงเชฟเช•เซƒเชค เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชฎเชพเชŸเซ‡ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช. เช† เชญเชพเช— เช–เซ‚เชฌ เชœ เชธเชฐเชณ เช…เชจเซ‡ เชญเซ‚เชฒ เช•เชฐเชตเซ€ เชฎเซเชถเซเช•เซ‡เชฒ เช›เซ‡: เช…เชฎเซ‡ เชฎเซ‡เชธเซ‡เชœ เช•เชพเช‰เชจเซเชŸเชฐเชจเซ‡ เชตเชงเชพเชฐเซ€เช เช›เซ€เช, เชฎเซ‡เชธเซ‡เชœเชจเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเซ€เช เช›เซ€เช, เช•เชพเช‰เชจเซเชŸเชฐเชจเซ‡ เชชเซเชฐเชฎเชพเชฃเชฟเชค (MAC) เช•เชฐเซ€เช เช›เซ€เช เช…เชจเซ‡ เชธเชพเช‡เชซเชฐเชŸเซ‡เช•เซเชธเซเชŸ เชฎเซ‹เช•เชฒเซ€เช เช›เซ€เช. เชธเช‚เชฆเซ‡เชถ เชชเซเชฐเชพเชชเซเชค เช•เชฐเชคเซ€ เชตเช–เชคเซ‡, เช…เชฎเซ‡ เชคเชชเชพเชธเซ€เช เช›เซ€เช เช•เซ‡ เช•เชพเช‰เชจเซเชŸเชฐ เชชเชพเชธเซ‡ เช…เชชเซ‡เช•เซเชทเชฟเชค เชฎเซ‚เชฒเซเชฏ เช›เซ‡, เช•เชพเช‰เชจเซเชŸเชฐ เชธเชพเชฅเซ‡ เชธเชพเช‡เชซเชฐเชŸเซ‡เช•เซเชธเซเชŸเชจเซ‡ เชชเซเชฐเชฎเชพเชฃเชฟเชค เช•เชฐเซ‹ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชกเชฟเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเซ‹. เชนเซ‡เชจเซเชกเชถเซ‡เช• เชธเช‚เชฆเซ‡เชถเชพเช“ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพ, เชธเช‚เชฆเซ‡เชถเชพเช“ เชชเชฐเชฟเชตเชนเชจ เช•เชฐเชตเชพ เช…เชจเซ‡ เชคเซ‡เชฎเชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชชเซเชฐเชฎเชพเชฃเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชฎเชพเชฐเซ‡ เช•เชˆ เช•เซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเซ‹ เชœเซ‹เชˆเช? เช† เชฌเชงเชพ เช•เชพเชฐเซเชฏเซ‹ เชฎเชพเชŸเซ‡ เชเช• เช•เซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเซ‹ เชœเซ‹เช–เชฎเซ€ เช…เชจเซ‡ เช…เชตเชฟเชตเซ‡เช•เซ€ เช›เซ‡. เชตเชฟเชถเชฟเชทเซเชŸ เช•เชพเชฐเซเชฏเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เซ€เช“ เชœเชจเชฐเซ‡เชŸ เช•เชฐเชตเซ€ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡ เช•เซ‡เชกเซ€เชเชซ (เช•เซ€ เชตเซเชฏเซเชคเซเชชเชจเซเชจ เช•เชพเชฐเซเชฏ). เชซเชฐเซ€เชฅเซ€, เชšเชพเชฒเซ‹ เชตเชพเชณ เชตเชฟเชญเชพเชœเซ€เชค เชจ เช•เชฐเซ€เช เช…เชจเซ‡ เช•เช‚เชˆเช• เชถเซ‹เชง เช•เชฐเซ€เช: เชเชš.เช•เซ‡.เชกเซ€.เชเชซ. เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏเชฅเซ€ เชœเชพเชฃเซ€เชคเซเช‚ เช›เซ‡, เชธเชพเชฐเซ€ เชฐเซ€เชคเซ‡ เชธเช‚เชถเซ‹เชงเชจ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เช›เซ‡ เช…เชจเซ‡ เช•เซ‹เชˆ เชœเชพเชฃเซ€เชคเซ€ เชธเชฎเชธเซเชฏเชพเช“ เชจเชฅเซ€. เช•เชฎเชจเชธเซ€เชฌเซ‡, เชฎเซ‚เชณ เชชเชพเชฏเชฅเซ‹เชจ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€เชฎเชพเช‚ เช† เช•เชพเชฐเซเชฏ เชจเชฅเซ€, เชคเซ‡เชฅเซ€ เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช hkdf เชชเซเชฒเชพเชธเซเชŸเชฟเช• เชฌเซ‡เช—. HKDF เช†เช‚เชคเชฐเชฟเช• เชฐเซ€เชคเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡ HMAC, เชœเซ‡ เชฌเชฆเชฒเชพเชฎเชพเช‚ เชนเซ‡เชถ เชซเช‚เช•เซเชถเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡. เชตเชฟเช•เชฟเชชเซ€เชกเชฟเชฏเชพ เชชเซƒเชทเซเช  เชชเชฐ เชชเชพเชฏเชฅเซ‹เชจเชฎเชพเช‚ เชเช• เช‰เชฆเชพเชนเชฐเชฃ เช…เชฎเชฒเซ€เช•เชฐเชฃ เช•เซ‹เชกเชจเซ€ เชฅเซ‹เชกเซ€เช• เชฒเชพเช‡เชจ เชฒเซ‡ เช›เซ‡. 34.10/2012/256 เชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เช†เชชเชฃเซ‡ เชนเซ‡เชถ เชซเช‚เช•เซเชถเชจ เชคเชฐเซ€เช•เซ‡ เชธเซเชŸเซเชฐเชฟเชฌเซ‹เช—-XNUMX เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชถเซเช‚. เช…เชฎเชพเชฐเชพ เช•เซ€ เชเช—เซเชฐเซ€เชฎเซ‡เชจเซเชŸ เชซเช‚เช•เซเชถเชจเชจเชพ เช†เช‰เชŸเชชเซเชŸเชจเซ‡ เชธเซ‡เชถเชจ เช•เซ€ เช•เชนเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡, เชœเซ‡เชฎเชพเช‚เชฅเซ€ เช—เซเชฎ เชฅเชฏเซ‡เชฒ เชธเชชเซเชฐเชฎเชพเชฃ เชœเชจเชฐเซ‡เชŸ เชฅเชถเซ‡:

    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)
    

    เชนเซ‡เชจเซเชกเชถเซ‡เช•เชŸเซ€เชฌเซ€เชเชธ เชชเชฐ เชนเชธเซเชคเชพเช•เซเชทเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชนเซ‡เชจเซเชกเชถเซ‡เช•เชŸเซ€เชฌเซ€เช‡ - เชถเซเช‚ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชนเซเช‚ เชคเชฎเชพเชฐเซเช‚ เชงเซเชฏเชพเชจ MsgHandshake1 เชฎเชพเช‚ ukm เชซเซ€เชฒเซเชก เชคเชฐเชซ เชฆเซ‹เชฐเซเช‚ เช›เซเช‚. 34.10 VKO, เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡เชฒเซ€ เช•เซ€เชจเชพ เชตเชงเซ เชฐเซ‡เชจเซเชกเชฎเชพเช‡เชเซ‡เชถเชจ เชฎเชพเชŸเซ‡, UKM (เชฏเซเชเชฐ เช•เซ€เช‡เช‚เช— เชฎเชŸเชฟเชฐเชฟเชฏเชฒ) เชชเซ‡เชฐเชพเชฎเซ€เชŸเชฐเชจเซ‹ เชธเชฎเชพเชตเซ‡เชถ เช•เชฐเซ‡ เช›เซ‡ - เชฎเชพเชคเซเชฐ เชตเชงเชพเชฐเชพเชจเซ€ เชเชจเซเชŸเซเชฐเซ‹เชชเซ€.

    เช•เซ‹เชกเชฎเชพเช‚ เช•เซเชฐเชฟเชชเซเชŸเซ‹เช—เซเชฐเชพเชซเซ€ เช‰เชฎเซ‡เชฐเชตเชพเชจเซเช‚

    เชšเชพเชฒเซ‹ เชฎเซ‚เชณ เช•เซ‹เชกเชฎเชพเช‚ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡เชฒเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹เชจเซ‡ เชœ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเชˆเช, เช•เชพเชฐเชฃ เช•เซ‡ เชซเซเชฐเซ‡เชฎเชตเชฐเซเช• เชธเชฎเชพเชจ เชฐเชนเซเชฏเซเช‚ (เชนเช•เซ€เช•เชคเชฎเชพเช‚, เช…เช‚เชคเชฟเชฎ เช…เชฎเชฒเซ€เช•เชฐเชฃ เชชเชนเซ‡เชฒเชพ เชฒเช–เชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเชคเซเช‚, เช…เชจเซ‡ เชชเช›เซ€ เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชคเชฎเชพเชฎ เชธเช‚เช•เซ‡เชคเชฒเชฟเชชเซ€เชจเซ‡ เช•เชพเชชเซ€ เชจเชพเช–เชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชนเชคเซ€).

    เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เช…เชจเซ‡ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเซเชธเชจเซ€ เช“เชณเช– เชนเชพเชฅ เชงเชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡, เชคเซ‡เชฅเซ€ เชคเซ‡เชฎเชจเซ‡ เชนเชตเซ‡ เช•เซเชฏเชพเช‚เช• เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏ เชธเซเชงเซ€ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เชธเชฐเชณเชคเชพ เชฎเชพเชŸเซ‡, เช…เชฎเซ‡ เช† เชฐเซ€เชคเซ‡ JSON เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช:

    {
        "our": {
            "prv": "21254cf66c15e0226ef2669ceee46c87b575f37f9000272f408d0c9283355f98",
            "pub": "938c87da5c55b27b7f332d91b202dbef2540979d6ceaa4c35f1b5bfca6df47df0bdae0d3d82beac83cec3e353939489d9981b7eb7a3c58b71df2212d556312a1"
        },
        "their": {
            "alice": "d361a59c25d2ca5a05d21f31168609deeec100570ac98f540416778c93b2c7402fd92640731a707ec67b5410a0feae5b78aeec93c4a455a17570a84f2bc21fce",
            "bob": "aade1207dd85ecd283272e7b69c078d5fae75b6e141f7649ad21962042d643512c28a2dbdc12c7ba40eb704af920919511180c18f4d17e07d7f5acd49787224a"
        }
    }
    

    เช…เชฎเชพเชฐเซ€ - เช…เชฎเชพเชฐเซ€ เช•เซ€ เชœเซ‹เชกเซ€, เชนเซ‡เช•เซเชธเชพเชกเซ‡เชธเชฟเชฎเชฒ เช–เชพเชจเช—เซ€ เช…เชจเซ‡ เชœเชพเชนเซ‡เชฐ เช•เซ€. เชคเซ‡เชฎเชจเชพ โ€” เชตเชพเชฐเซเชคเชพเชฒเชพเชช เช•เชฐเชจเชพเชฐเชพเช“เชจเชพ เชจเชพเชฎ เช…เชจเซ‡ เชคเซ‡เชฎเชจเซ€ เชœเชพเชนเซ‡เชฐ เชšเชพเชตเซ€เช“. เชšเชพเชฒเซ‹ เช†เชฆเซ‡เชถ เชตเชพเช•เซเชฏ เชฆเชฒเซ€เชฒเซ‹ เชฌเชฆเชฒเซ€เช เช…เชจเซ‡ 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 เชฌเชพเช‡เชŸเซเชธเชจเชพ เชธเชฎเซ‚เชน เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชคเซเช‚ เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เชธเชพเชฅเซ‡ เชฎเซ‹เชŸเซ€ เชธเช‚เช–เซเชฏเชพเชฎเชพเช‚, เชคเซ‡เชฅเซ€ เช…เชฎเชพเชฐเซ€ เช–เชพเชจเช—เซ€ เช•เซ€ (เชฏเซเชฐเซ‡เชจเซเชกเชฎ(32)) เชจเซ‡ gost3410.prv_unmarshal() เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชจเช‚เชฌเชฐเชฎเชพเช‚ เชฐเซ‚เชชเชพเช‚เชคเชฐเชฟเชค เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เชœเชพเชนเซ‡เชฐ เช•เซ€ gost3410.public_key() เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช–เชพเชจเช—เซ€ เช•เซ€เชฎเชพเช‚เชฅเซ€ เชจเชฟเชฐเซเชงเชพเชฐเชฟเชค เชฐเซ€เชคเซ‡ เชจเช•เซเช•เซ€ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€ 34.10 เช เชฌเซ‡ เชฎเซ‹เชŸเซ€ เชธเช‚เช–เซเชฏเชพเช“ เช›เซ‡ เชœเซ‡เชจเซ‡ gost3410.pub_marshal() เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชธเซเชŸเซ‹เชฐเซ‡เชœ เช…เชจเซ‡ เชŸเซเชฐเชพเชจเซเชธเชฎเชฟเชถเชจเชจเซ€ เชธเชฐเชณเชคเชพ เชฎเชพเชŸเซ‡ เชฌเชพเชˆเชŸ เชธเชฟเช•เซเชตเชจเซเชธเชฎเชพเช‚ เชฐเซ‚เชชเชพเช‚เชคเชฐเชฟเชค เช•เชฐเชตเชพเชจเซ€ เชชเชฃ เชœเชฐเซ‚เชฐ เช›เซ‡.

    JSON เชซเชพเช‡เชฒ เชตเชพเช‚เชšเซเชฏเชพ เชชเช›เซ€, เชคเซ‡ เชฎเซเชœเชฌ เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เชจเซ‡ gost3410.pub_unmarshal() เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชชเชพเช›เซ€ เชฐเซ‚เชชเชพเช‚เชคเชฐเชฟเชค เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เช…เชฎเชจเซ‡ เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เชฎเชพเช‚เชฅเซ€ เชนเซ‡เชถเชจเชพ เชฐเซ‚เชชเชฎเชพเช‚ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเซเชธเชจเชพ เช“เชณเช–เช•เชฐเซเชคเชพเช“ เชชเซเชฐเชพเชชเซเชค เชฅเชถเซ‡, เชคเซ‡เชฅเซ€ เชคเซ‡เช“ เชคเชฐเชค เชœ เช…เช—เชพเช‰เชฅเซ€ เช—เชฃเชคเชฐเซ€ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡ เช…เชจเซ‡ เชเชกเชชเซ€ เชถเซ‹เชง เชฎเชพเชŸเซ‡ เชถเชฌเซเชฆเช•เซ‹เชถเชฎเชพเช‚ เชฎเซ‚เช•เซ€ เชถเช•เชพเชฏ เช›เซ‡. Stribog-256 hash gost34112012256.GOST34112012256(), เชœเซ‡ เชนเซ‡เชถ เชซเช‚เช•เซเชถเชจเซเชธเชจเชพ เชนเซ‡เชถเชฒเชฟเชฌ เช‡เชจเซเชŸเชฐเชซเซ‡เชธเชจเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เชฐเซ€เชคเซ‡ เชธเช‚เชคเซเชทเซเชŸ เช•เชฐเซ‡ เช›เซ‡.

    เช†เชฐเช‚เชญ เช•เชฐเชจเชพเชฐ เช•เซ‹เชฐเซ‹เชŸเซ€เชจ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชฆเชฒเชพเชˆ เช›เซ‡? เชฌเชงเซเช‚ เชนเซ‡เชจเซเชกเชถเซ‡เช• เชฏเซ‹เชœเชจเชพ เชฎเซเชœเชฌ เช›เซ‡: เช…เชฎเซ‡ เชเช• เช•เซ‚เช•เซ€ (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()
    

    • เช…เชฎเซ‡ เชชเซเชฐเชคเชฟเชธเชพเชฆเชจเซ€ เชฐเชพเชน เชœเซ‹เชˆเช เช›เซ€เช เช…เชจเซ‡ เช†เชตเชจเชพเชฐเชพ เชธเช‚เชฆเซ‡เชถเชจเซ‡ เชกเซ€เช•เซ‹เชก เช•เชฐเซ€เช เช›เซ€เช;
    • เช–เชพเชคเชฐเซ€ เช•เชฐเซ‹ เช•เซ‡ เชคเชฎเซ‡ เชนเซ‡เชจเซเชกเชถเซ‡เช•1 เชฎเซ‡เชณเชตเซ‹ เช›เซ‹;
    • เชตเชฟเชฐเซ‹เชงเซ€ เชชเช•เซเชทเชจเซ€ เช•เซเชทเชฃเชฟเช• เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€เชจเซ‡ เชกเซ€เช•เซ‹เชก เช•เชฐเซ‹ เช…เชจเซ‡ เชธเชคเซเชฐ เช•เซ€เชจเซ€ เช—เชฃเชคเชฐเซ€ เช•เชฐเซ‹;
    • เช…เชฎเซ‡ เชธเช‚เชฆเซ‡เชถเชจเชพ 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-เชฌเซ€เชŸ เชจเช‚เชฌเชฐ เช›เซ‡ (เชฏเซเชฐเซ‡เชจเซเชกเชฎ(8)), เชœเซ‡เชจเซ‡ gost3410_vko.ukm_unmarshal() เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชคเซ‡เชจเชพ เชฌเชพเชˆเชŸ เชชเซเชฐเชคเชฟเชจเชฟเชงเชฟเชคเซเชตเชฎเชพเช‚เชฅเซ€ เชกเซ€เชธเซ€เชฐเชฟเชฏเชฒเชพเชˆเชเซ‡เชถเชจเชจเซ€ เชชเชฃ เชœเชฐเซ‚เชฐ เช›เซ‡. 34.10/2012/256 เชฎเชพเชŸเซ‡ VKO เชซเช‚เช•เซเชถเชจ 3410-bit gost34102012256_vko.kek_XNUMX() (KEK - เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เช•เซ€) เช›เซ‡.

    เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡เชฒ เชธเชคเซเชฐ เช•เซ€ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ 256-เชฌเซ€เชŸ เชธเซเชฏเซเชกเซ‹-เชฐเซ‡เชจเซเชกเชฎ เชฌเชพเชˆเชŸ เชธเชฟเช•เซเชตเชจเซเชธ เช›เซ‡. เชคเซ‡เชฅเซ€, เชคเซ‡เชจเซ‹ เชคเชฐเชค เชœ HKDF เช•เชพเชฐเซเชฏเซ‹เชฎเชพเช‚ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡. GOST34112012256 hashlib เชˆเชจเซเชŸเชฐเชซเซ‡เชธเชจเซ‡ เชธเช‚เชคเซเชทเซเชŸ เช•เชฐเชคเซเช‚ เชนเซ‹เชตเชพเชฅเซ€, เชคเซ‡เชจเซ‹ เชคเชฐเชค เชœ Hkdf เชตเชฐเซเช—เชฎเชพเช‚ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡. เช…เชฎเซ‡ เชฎเซ€เช เซเช‚ (Hkdf เชจเซ€ เชชเซเชฐเชฅเชฎ เชฆเชฒเซ€เชฒ) เชจเซ‹ เช‰เชฒเซเชฒเซ‡เช– เช•เชฐเชคเชพ เชจเชฅเซ€, เช•เชพเชฐเชฃ เช•เซ‡ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡เชฒ เช•เซ€, เชธเชนเชญเชพเช—เซ€ เช•เซ€ เชœเซ‹เชกเซ€เชจเซ€ เช•เซเชทเชฃเชฟเช•เชคเชพเชจเซ‡ เช•เชพเชฐเชฃเซ‡, เชฆเชฐเซ‡เช• เชธเชคเซเชฐ เชฎเชพเชŸเซ‡ เช…เชฒเช— เชนเชถเซ‡ เช…เชจเซ‡ เชคเซ‡ เชชเชนเซ‡เชฒเชพเชฅเซ€ เชœ เชชเซ‚เชฐเชคเซ€ เชเชจเซเชŸเซเชฐเซ‹เชชเซ€ เชงเชฐเชพเชตเซ‡ เช›เซ‡. kdf.expand() เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡ เชชเชนเซ‡เชฒเชพเชฅเซ€ เชœ เช—เซเชฐเชพเชถเซ‹เชชเชฐ เชฎเชพเชŸเซ‡ เชœเชฐเซ‚เชฐเซ€ 256-เชฌเซ€เชŸ เช•เซ€เช“เชจเซเช‚ เช‰เชคเซเชชเชพเชฆเชจ เช•เชฐเซ‡ เช›เซ‡.

    เช†เช—เชณ, เช†เชตเชจเชพเชฐเชพ เชธเช‚เชฆเซ‡เชถเชพเชจเชพ TBE เช…เชจเซ‡ TBS เชญเชพเช—เซ‹ เชคเชชเชพเชธเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡:

    • เช‡เชจเช•เชฎเชฟเช‚เช— เชธเชฟเชซเชฐเชŸเซ‡เช•เซเชธเซเชŸ เชชเชฐ MAC เชจเซ€ เช—เชฃเชคเชฐเซ€ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเชชเชพเชธเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡;
    • เชธเชพเช‡เชซเชฐเชŸเซ‡เช•เซเชธเซเชŸ เชกเชฟเช•เซเชฐเชฟเชชเซเชŸ เชฅเชฏเซ‡เชฒ เช›เซ‡;
    • TBE เชฎเชพเชณเช–เซเช‚ เชกเซ€เช•เซ‹เชก เชฅเชฏเซ‡เชฒ เช›เซ‡;
    • เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเชจเซ€ เช“เชณเช–เช•เชฐเซเชคเชพ เชคเซ‡เชจเซ€ เชชเชพเชธเซ‡เชฅเซ€ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡ เชคเชชเชพเชธเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช•เซ‡ เชคเซ‡ เช†เชชเชฃเชจเซ‡ เชฌเชฟเชฒเช•เซเชฒ เช“เชณเช–เซ‡ เช›เซ‡ เช•เซ‡ เช•เซ‡เชฎ;
    • เช† เช“เชณเช–เช•เชฐเซเชคเชพ เชชเชฐ MAC เชจเซ€ เช—เชฃเชคเชฐเซ€ เช…เชจเซ‡ เชคเชชเชพเชธ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡;
    • TBS เชธเซเชŸเซเชฐเช•เซเชšเชฐ เชชเชฐเชจเซ€ เชธเชนเซ€ เชšเช•เชพเชธเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชœเซ‡เชฎเชพเช‚ เชฌเช‚เชจเซ‡ เชชเช•เซเชทเซ‹เชจเซ€ เช•เซ‚เช•เซ€ เช…เชจเซ‡ เชตเชฟเชฐเซ‹เชงเซ€ เชชเช•เซเชทเชจเซ€ เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซเชทเชฃเชฟเช• เช•เซ€เชจเซ‹ เชธเชฎเชพเชตเซ‡เชถ เชฅเชพเชฏ เช›เซ‡. เชนเชธเซเชคเชพเช•เซเชทเชฐ เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชฏเซเชŸเชฐเชจเซ€ เชฒเชพเช‚เชฌเชพ เช—เชพเชณเชพเชจเซ€ เชธเชนเซ€ เช•เซ€ เชฆเซเชตเชพเชฐเชพ เชšเช•เชพเชธเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

     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/XNUMX เชตเชฟเชตเชฟเชง เชตเชฐเซเชฃเชจ เช•เชฐเซ‡ เช›เซ‡ เชฌเซเชฒเซ‹เช• เชธเชพเช‡เชซเชฐ เช“เชชเชฐเซ‡เชŸเชฟเช‚เช— เชฎเซ‹เชกเซเชธ 34.12/2015/3413 เชฅเซ€. เชคเซ‡เชฎเชพเช‚เชฅเซ€ เช…เชจเซเช•เชฐเชฃ เชฆเชพเช–เชฒ เช…เชจเซ‡ MAC เช—เชฃเชคเชฐเซ€เช“ เชœเชจเชฐเซ‡เชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชเช• เชฎเซ‹เชก เช›เซ‡. PyGOST เชฎเชพเช‚ เช† gost34.12.mac() เช›เซ‡. เช† เชฎเซ‹เชก เชฎเชพเชŸเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชซเช‚เช•เซเชถเชจ (เชกเซ‡เชŸเชพเชจเซ‹ เชเช• เชฌเซเชฒเซ‹เช• เชฎเซ‡เชณเชตเชตเซ‹ เช…เชจเซ‡ เชชเชฐเชค เช•เชฐเชตเซ‹), เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชฌเซเชฒเซ‹เช•เชจเซเช‚ เช•เชฆ เช…เชจเซ‡ เชนเช•เซ€เช•เชคเชฎเชพเช‚, เชกเซ‡เชŸเชพ เชชเซ‹เชคเซ‡ เชœ เชชเชธเชพเชฐ เช•เชฐเชตเซ‹ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡. เชถเชพ เชฎเชพเชŸเซ‡ เชคเชฎเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชฌเซเชฒเซ‹เช•เชจเชพ เช•เชฆเชจเซ‡ เชนเชพเชฐเซเชกเช•เซ‹เชก เช•เชฐเซ€ เชถเช•เชคเชพ เชจเชฅเซ€? 2015/128/64 เชฎเชพเชคเซเชฐ XNUMX-เชฌเซ€เชŸ เช—เซเชฐเชพเชถเซ‹เชชเชฐ เชธเชพเช‡เชซเชฐ เชœ เชจเชนเซ€เช‚, เชชเชฃ XNUMX-เชฌเซ€เชŸเชจเซเช‚ เชชเชฃ เชตเชฐเซเชฃเชจ เช•เชฐเซ‡ เช›เซ‡ เชฎเซ‡เช—เซเชฎเชพ - เชธเชนเซ‡เชœ เชธเช‚เชถเซ‹เชงเชฟเชค GOST 28147-89, เช•เซ‡เชœเซ€เชฌเซ€เชฎเชพเช‚ เชชเชพเช›เซเช‚ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เช›เซ‡ เช…เชจเซ‡ เชนเชœเซ เชชเชฃ เช‰เชšเซเชšเชคเชฎ เชธเซเชฐเช•เซเชทเชพ เชฅเซเชฐเซ‡เชถเซ‹เชฒเซเชกเชฎเชพเช‚เชจเซเช‚ เชเช• เช›เซ‡.

    เช•เซเชเชจเซ‡เชšเชฟเช•เชจเซ‡ gost.3412.GOST3412Kuznechik(key) เชชเชฐ เช•เซ‰เชฒ เช•เชฐเซ€เชจเซ‡ เชชเซเชฐเชพเชฐเช‚เชญ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช…เชจเซ‡ 34.13 เชซเช‚เช•เซเชถเชจเชฎเชพเช‚ เชชเชธเชพเชฐ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชฏเซ‹เช—เซเชฏ .encrypt()/.decrypt() เชชเชฆเซเชงเชคเชฟเช“ เชตเชกเซ‡ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชชเชฐเชค เช•เชฐเซ‡ เช›เซ‡. MAC เชจเซ€ เช—เชฃเชคเชฐเซ€ เชจเซ€เชšเซ‡ เชชเซเชฐเชฎเชพเชฃเซ‡ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡: gost3413.mac(GOST3412Kuznechik(key).encrypt, KUZNECHIK_BLOCKSIZE, เชธเชพเช‡เชซเชฐเชŸเซ‡เช•เซเชธเซเชŸ). เช—เชฃเชคเชฐเซ€ เช•เชฐเซ‡เชฒ เช…เชจเซ‡ เชชเซเชฐเชพเชชเซเชค เช•เชฐเซ‡เชฒ MAC เชจเซ€ เชธเชฐเช–เชพเชฎเชฃเซ€ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชคเชฎเซ‡ เชฌเชพเชˆเชŸ เชธเซเชŸเซเชฐเซ€เช‚เช—เซเชธเชจเซ€ เชธเชพเชฎเชพเชจเซเชฏ เชธเชฐเช–เชพเชฎเชฃเซ€ (==) เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เชคเชพ เชจเชฅเซ€, เช•เชพเชฐเชฃ เช•เซ‡ เช† เช•เชพเชฎเช—เซ€เชฐเซ€ เชธเชฐเช–เชพเชฎเชฃเซ€ เชธเชฎเชฏเชจเซ‡ เชฒเซ€เช• เช•เชฐเซ‡ เช›เซ‡, เชœเซ‡ เชธเชพเชฎเชพเชจเซเชฏ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เช˜เชพเชคเช• เชจเชฌเชณเชพเชˆเช“ เชคเชฐเชซ เชฆเซ‹เชฐเซ€ เชถเช•เซ‡ เช›เซ‡ เชœเซ‡เชฎ เช•เซ‡ เชฌเซ€เชธเซเชŸ TLS เชชเชฐ เชนเซเชฎเชฒเชพ. เช† เชฎเชพเชŸเซ‡ เชชเชพเชฏเชฅเซ‹เชจ เชชเชพเชธเซ‡ เช–เชพเชธ เช•เชพเชฐเซเชฏ เช›เซ‡, 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, เชธเชพเชฆเซ‹ เชŸเซ‡เช•เซเชธเซเชŸ, iv). เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชฌเซเชฒเซ‹เช•เชจเซ€ เชฌเชฐเชพเชฌเชฐ เช…เชกเชงเซ€ เชฒเช‚เชฌเชพเชˆ เชงเชฐเชพเชตเชคเชพ เชชเซเชฐเชพเชฐเช‚เชญเชฟเช• เชตเซ‡เช•เซเชŸเชฐเชจเซ‹ เช‰เชฒเซเชฒเซ‡เช– เช•เชฐเชตเซ‹ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡. เชœเซ‹ เช…เชฎเชพเชฐเซ€ เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เช•เซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชซเช•เซเชค เชเช• เชธเช‚เชฆเซ‡เชถเชจเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ (เช˜เชฃเชพ เชฌเซเชฒเซ‹เช•เชฎเชพเช‚เชฅเซ€ เชนเซ‹เชตเชพ เช›เชคเชพเช‚), เชคเซ‹ เชถเซ‚เชจเซเชฏ เช†เชฐเช‚เชญ เชตเซ‡เช•เซเชŸเชฐ เชธเซ‡เชŸ เช•เชฐเชตเซเช‚ เชธเชฒเชพเชฎเชค เช›เซ‡. เชนเซ‡เชจเซเชกเชถเซ‡เช• เชธเช‚เชฆเซ‡เชถเชพเชจเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฎเซ‡ เชฆเชฐเซ‡เช• เชตเช–เชคเซ‡ เช…เชฒเช— เช•เซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช.

    เชนเชธเซเชคเชพเช•เซเชทเชฐ gost3410.verify() เชจเซ€ เชšเช•เชพเชธเชฃเซ€ เช•เชฐเชตเซ€ เชคเซเชšเซเช› เช›เซ‡: เช…เชฎเซ‡ เชœเซ‡ เชฒเช‚เชฌเช—เซ‹เชณ เชตเชณเชพเช‚เช•เชจเซ‡ เช…เช‚เชฆเชฐเชฅเซ€ เชชเชธเชพเชฐ เช•เชฐเซ€เช เช›เซ€เช (เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เช…เชฎเชพเชฐเชพ GOSTIM เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒเชฎเชพเช‚ เชฐเซ‡เช•เซ‹เชฐเซเชก เช•เชฐเซ€เช เช›เซ€เช), เชธเชนเซ€ เช•เชฐเชจเชพเชฐเชจเซ€ เชธเชพเชฐเซเชตเชœเชจเชฟเช• เช•เซ€ (เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚ เช•เซ‡ เช† เชฌเซ‡เชจเซ‹ เชŸเซเชชเชฒ เชนเซ‹เชตเซ‹ เชœเซ‹เชˆเช. เชฎเซ‹เชŸเซ€ เชธเช‚เช–เซเชฏเชพเช“, เช…เชจเซ‡ เชฌเชพเชˆเชŸ เชธเซเชŸเซเชฐเชฟเช‚เช— เชจเชนเซ€เช‚), 34.11/2012/XNUMX เชนเซ‡เชถ เช…เชจเซ‡ เชธเชนเซ€ เชชเซ‹เชคเซ‡.

    เช†เช—เชณ, เช‡เชจเชฟเชถเชฟเชฏเซ‡เชŸเชฐเชฎเชพเช‚ เช…เชฎเซ‡ เชนเซ‡เชจเซเชกเชถเซ‡เช• 2 เชจเซ‡ เชนเซ‡เชจเซเชกเชถเซ‡เช• เชฎเซ‡เชธเซ‡เชœ เชคเซˆเชฏเชพเชฐ เช•เชฐเซ€เช เช›เซ€เช เช…เชจเซ‡ เชฎเซ‹เช•เชฒเซ€เช เช›เซ€เช, เช…เชฎเซ‡ เชตเซ‡เชฐเชฟเชซเชฟเช•เซ‡เชถเชจ เชฆเชฐเชฎเชฟเชฏเชพเชจ เชœเซ‡ เช•เซเชฐเชฟเชฏเชพเช“ เช•เชฐเซ€ เชนเชคเซ€ เชคเซ‡ เชœ เช•เซเชฐเชฟเชฏเชพเช“ เช•เชฐเซ€เชจเซ‡, เชฎเชพเชคเซเชฐ เชธเชฎเชชเซเชฐเชฎเชพเชฃเชฐเซ€เชคเซ‡: เชšเซ‡เช• เช•เชฐเชตเชพเชจเซ‡ เชฌเชฆเชฒเซ‡ เช…เชฎเชพเชฐเซ€ เช•เซ€ เชชเชฐ เชธเชนเซ€ เช•เชฐเชตเซ€ เชตเช—เซ‡เชฐเซ‡...

     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 เช•เชจเซ‡เช•เซเชถเชจ เชชเชฐ เชฎเซ‹เช•เชฒเชคเชพ เชชเชนเซ‡เชฒเชพ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเซ‡ เช›เซ‡. เชฆเชฐเซ‡เช• เชธเช‚เชฆเซ‡เชถเชฎเชพเช‚ เชเช•เชตเชฟเชง เชฐเซ€เชคเซ‡ เชตเชงเชคเซ€ เชœเชคเซ€ เชจเซ‹เชจเซเชธ เชนเซ‹เชฏ เช›เซ‡, เชœเซ‡ เชœเซเชฏเชพเชฐเซ‡ เช•เชพเช‰เชจเซเชŸเชฐ เชฎเซ‹เชกเชฎเชพเช‚ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เชคเซเชฏเชพเชฐเซ‡ เช†เชฐเช‚เชญ เชตเซ‡เช•เซเชŸเชฐ เชชเชฃ เชนเซ‹เชฏ เช›เซ‡. เชฆเชฐเซ‡เช• เชธเช‚เชฆเซ‡เชถ เช…เชจเซ‡ เชธเช‚เชฆเซ‡เชถ เชฌเซเชฒเซ‹เช•เชจเซ€ เช…เชฒเช— เช•เชพเช‰เชจเซเชŸเชฐ เช•เชฟเช‚เชฎเชค เชนเซ‹เชตเชพเชจเซ€ เช–เชพเชคเชฐเซ€ เช†เชชเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

    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, เชเชจ.เชเชจ.เชธเซ€.เชชเซ€., GoVPN, GOSTIM เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เช›เซ‡ เชฎเชซเชค เชธเซ‹เชซเซเชŸเชตเซ‡เชฐ, เชถเชฐเชคเซ‹ เชนเซ‡เช เชณ เชตเชฟเชคเชฐเชฟเชค GPLv3 +.

    เชธเซ‡เชฐเซเช—เซ‡เชˆ เชฎเชพเชคเซเชตเซ€เชต, เชธเชพเชฏเชซเชฐเชชเช‚เช•, เชธเชญเซเชฏ SPO เชซเชพเช‰เชจเซเชกเซ‡เชถเชจ, Python/Go เชตเชฟเช•เชพเชธเช•เชฐเซเชคเชพ, เชฎเซเช–เซเชฏ เชจเชฟเชทเซเชฃเชพเชค FSUE "STC "เชเชŸเชฒเชพเชธ".

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹