Comments 25
КДПВ огонь
if padding != 0 {
repeat := bytes.Repeat([]byte("\x00"), aes.BlockSize-(padding))
content = append(content, repeat...)
}
...
encrypted = bytes.Trim(encrypted, string([]byte("\x00")))
Лучше так не делать, т.к. если в конце сообщения окажутся нулевые байты, то они будут откушены. Лучше воспользоваться padding'ом из PKCS#7
Однако, шифруется json, и он всегда заканчивается на печатные байты "}" или "]", поэтому в текущей реализации проблем быть не должно.
habr.com/ru/post/452200 — вот тут есть пример гораздо более безопасного решения, но на Python. Из сложностей: ASN.1 вместо простой сериализации как у вас (простота это тоже хорошо). И просто для справки: если хочется ГОСТ криптографию, то вот для Go есть GoGOST: gogost.cypherpunks.ru
По логам — мы используем github.com/uber-go/zap с небольшой оберткой, которая позволяет нам создавать нужные аппендеры на лету. Форматирование zap тоже поддерживает, но если хочется свой формат лог записей, то нужно написать немного кода. Универсализма как в log4j я пока не видел.
Что касается конкретно вашей реализации:
1) ID пира должен быть хэшем от его статического публичного ключа, иначе MITM
2) Эфемерные ключи не подписаны. Тоже MITM
2) Вместо AES-CBC лучше использовать AES-GCM/AES-GCM-SIV, либо добавить HMAC. У вас нет никакой проверки корректности расшифрованного текста, можно напихать туда что угодно и собеседник ничего не заподозрит
Это только то, что сразу бросилось в глаза
Спасибо за препарацию моей самоделки и за Noise Protocol.
Я расчитывал как раз на подобный разбор.
1) Сейчас ID пира есть его публичный ключ. Первоначально не ставил задачу его скрывать, да и протокол был бы не такой лаконичный, а на будущее учту этот момент. Правда, не совсем понял как это уязвимо для MITM?
2) Эфемерные ключи передаются в подписанном конверте, поэтому можно считать что они подписаны
func (p Proto) SendName(peer *Peer) {
/* ... */
sign := ed25519.Sign(p.privKey, handShake)
envelope := NewSignedEnvelope("HAND", p.PubKey[:], make([]byte, 32), sign, handShake)
}
Другое дело, что подпись проверяется, но реакция на некорректность реализована недостаточно.
3) Да, проверка корректности отсутствует. Была идея реализовать как в телеграмме AES+IGE. Была мысль, что контент сам себя провалидирует, если будет представлять собой gzip, в который я хотел упаковывать все сообщения для экономии трафика. А там уже проверки гзиповские будут. Но соглашусь, лучше использовать проверку корректности на основе режима шифрования.
Ниже уже кинули ссылку на репозиторий с кодом, можно его еще поковырять.
Технически статью осилить не способен, но за картинку плюс :)
причем с гуем на реакте, общением через один порт и вот этим всем
Полагаю, что возьми вы либп2п, навернка быстрее и лучше сбацаете (:
p2p мессерджер (кстати, есть ли русский синоним этому слову?).
Да. Мы в России его называем мессенджер :)
Если серьезно, то встречал разные, но "Система обмена мгновенными сообщениями" как-то сложно звучит, "болталка" — слишком несерьезно. Иногда встречал "чат", но это больше к виджету мессенджера, вставленному на сайт.
Интересная статья.
Думаю, многим будет интересно "потыкать" проект. Но для тех, кто go не собирал поначалу может быть сложно. Можно собрать проект под разные системы (благо в go кросс-компиляция несложная) и положить статическим бинарен на GitHub. Или в крайнем случае — Docker образ. Так они смогут его скачать и запустить, а вы получить обширную обратную связь.
Публичные (экспортируемые) методы пишутся с большой буквы, а приватные (неэкспортируемые) с маленькой. Такая себе инкапсуляция =)
golang.org/ref/spec#Exported_identifiers
Еще такое обучение нашел — огонь!
https://www.youtube.com/playlist?list=PLd-kTafWJCJOUBLIkAXI8h9Bxu4tOKlwn
Изучая go: пишем p2p мессенджер со сквозным шифрованием