Привет!
Мы уже показывали вам код, с помощью которого можно легко и просто реализовать end-to-end шифрование. Давайте пойдем дальше и, используя сервисы Virgil Security, разработаем безопасный IP мессенджер. Реализация безопасного IP мессенджера со встроенной функцией шифрования – задача далеко не тривиальная. В этой статье мы хотим рассказать как, используя Virgil API и Тwilio IP Messaging API, сделать этот процесс намного проще.
Часть 1: подготовительная
Прежде чем приступать к реализации нашего мессенджера необходимо выполнить пару предварительных действий:
- Создать аккаунт Twilio. Twilio — компания, предоставляющая в качестве сервиса средства коммуникации. С помощью Twilio задача разработки IP мессенджера сильно упрощается. Однако в этой статье наша цель гораздо более амбициозная. Напоминаем, что нам требуется безопасный(не путайте с анонимным) IP мессенджер с функцией end-to-end шифрования. Поэтому нам потребуется…
- Создать аккаунт Virgil Security. Аккаунт открывает возможность зарегистрировать приложение и получить VIRGIL_ACCESS_TOKEN — секретный ключ, позволяющий пользоваться сервисами Virgil Security.
После выполнения вышеперечисленных шагов вы станете счастливым обладателем следующего набора параметров:
- TWILIO_ACCOUNT_SID — идентификатор вашего аккаунта Twilio (доступен в вашем аккаунте).
- TWILIO_API_KEY — секретный ключ, используемый для аутентификации(сгенерировать его можно здесь).
- TWILIO_API_SECRET — дополнительная секретная информация, необходимая для аутентификации(создается тут).
- TWILIO_IPM_SERVICE_SID — экземпляр службы Twilio, в котором хранятся все данные о вашем приложении(создать можно по ссылке).
- VIRGIL_ACCESS_TOKEN — уникальный маркер, позволяющий получить доступ к Virgil Security API. Каждый запрос к API должен содержать VIRGIL_ACCESS_TOKEN. Получить его можно после создания Virgil приложения тут.
- VIRGIL_APP_PRIVATE_KEY — секретный ключ вашего Virgil приложения. Используется для создания validation token для аутентификации публичных ключей ваших пользователей в случае, если использование Identity Service нежелательно. Секретный ключ генерируется на вашем компьютере на странице вашего приложения после входа на сайт Virgil.
- VIRGIL_APP_PRIVATE_KEY_PASSWORD — все секретные ключи хранятся в зашифрованном виде, пароль для шифрования необходим при каждом использовании ключа.
Часть 2: основная
Отправка и получение сообщений в Twilio IP мессенджере происходит с помощью каналов. Каждый канал представляет собой отдельный чат, в котором одновременно может находиться неограниченное число собеседников. Взяв за основу Twilio IP мессенджер, покажем ключевые моменты реализации функции шифрования сообщений.
Прежде всего отметим, что использование сервисов Virgil Security возможно практически с любой платформы и на любом языке программирования. Для разработчиков доступен широкий набор SDK(C#, C/C++, Objective-C, Python, Java), облегчающих работу с Virgil Services. Однако их использование невозможно без VIRGIL_ACCESS_TOKEN. Т.к. мы уже получили VIRGIL_ACCESS_TOKEN на предварительном этапе, переходим непосредственно к разработке.
Наш мессенджер будет иметь клиент серверную структуру. Но все самое интересное(шифрование, отправление и расшифровка сообщений) будет происходит на стороне клиента, на ней мы и сосредоточим большую часть нашего внимания.
- Подключаем JavaScript SDK для Twilio и Virgil API:
<script src="https://cdn.virgilsecurity.com/packages/javascript/sdk/1.4.6/virgil-sdk.min.js" integrity="sha256-6gsCF73jFoEAcdAmVE8n+LCtUgzQ7j6svoCQxVxvmZ8=" crossorigin="anonymous"></script> <script src="https://media.twiliocdn.com/sdk/js/common/v0.1/twilio-common.min.js"></script> <script src="https://media.twiliocdn.com/sdk/rtc/js/ip-messaging/v0.10/twilio-ip-messaging.min.js"></script>
- Инициализируем работу с сервисами(токены для работы с API получаем от сервера):
// Инициализация Twilio var accessManager = new Twilio.AccessManager('%TWILIO_TOKEN%'); var messagingClient = new Twilio.IPMessaging.Client(accessManager); // Инициализация Virgil var virgil = new VirgilSDK("%VIRGIL_ACCESS_TOKEN%");
- С помощью Virgil SDK создадим пару ключей для нового пользователя Алиса:
var keyPair = virgil.crypto.generateKeyPair();
И получим следующее:-----BEGIN PUBLIC KEY----- MFswFQYHKoZIzj0CAQYKKwYBBAGXVQEFAQNCAAQO8ohmBRyclmcfQ38Lwmvv4Cau jyX6vWn8kJrR0RRfFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -----END PUBLIC KEY----- -----BEGIN EC PRIVATE KEY----- MHkCAQEEIFB+lOUvbb4WX+e3zLkAcYpvZR3qpQI8Ru/tcnciCMkIoAwGCisGAQQB l1UBBQGhRANCAAQO8ohmBRyclmcfQ38Lwmvv4CaujyX6vWn8kJrR0RRfFQAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -----END EC PRIVATE KEY-----
- Для того чтобы другие участники переписки могли отправлять Алисе зашифрованные сообщения, её публичный ключ должен быть размещен в хранилище ключей Virgil Keys Service. Процесс публикации ключа требует специального validation token, предотвращающего создание неподтвержденных ключей. Получить validation token можно с помощью нашего сервиса проверки личности Identity Service, либо сгенерировав его самостоятельно(на стороне сервера), используя VIRGIL_APP_PRIVATE_KEY:
VirgilSDK.utils.generateValidationToken( 'Alice', // значение идентификатора 'username', // тип идентификатора (любая строка) VIRGIL_APP_PRIVATE_KEY );
Получив validation token загрузим публичный ключ пользователя в хранилище:
var options = { public_key: keyPair.publicKey, private_key: keyPair.privateKey, identity: { type: 'username', value: 'Alice', validation_token: '%VALIDATION_TOKEN%' } }; virgil.cards.create(options).then(function (card){ myCard = card; console.log(card); });
После выполнения вышеописанных шагов в хранилище ключей Virgil Keys Service будет создана специальная структура данных, доступная любому пользователю вашего приложения, называемая Virgil Card и включающая следующие поля:
Пример созданной структуры данных Virgil Card:{ "id":"3e5a5d8b-e0b9-4be6-aa6b-66e3374c05b3", "authorized_by":"com.virgilsecurity.twilio-ip-messaging-demo", "hash":"QiWtZjZyIQhqZK7+3nZmIEWFBU+qI64EzSuqBcY+E7ZtKPwd4ZyU6gdfU/VzbTn6dHtfahCzHasN...", "created_at":"2016-05-03T14:34:08+0000", "public_key":{ "id":"359abe31-3344-453a-a292-fd98a83e500a", "public_key":"-----BEGIN PUBLIC KEY-----\nMFswFQYHKoZIzj0CAQYKKwYBBAGXVQEFAQNCAAQ...", "created_at":"2016-05-03T14:34:08+0000" }, "identity":{ "id":"965ea277-ab78-442c-93fe-6bf1d70aeb4b", "type":"username", "value":"Alice", "created_at":"2016-05-03T14:34:08+0000" } }
- Теперь пользователь Алиса готов к безопасному общению. Создадим для этого канал 'general':
// Создаем новый канал twilioClient.createChannel({ friendlyName: 'general' }).then(function(channel) { generalChannel = channel; });
- Любой желающий способен зайти в канал 'general' и отправить Алисе зашифрованное сообщение. Для этого находим в хранилище Virgil Keys Service публичный ключ Алисы и зашифровываем с его помощью секретное сообщение:
// Получаем список участников канала Promise.all(generalChannel.getMembers().map(function(member) { // Ищем Virgil Card всех участников переписки return virgil.cards.search({ value: member.identity, type: 'username' }) .then(function(cards){ return { recipientId: cards[0].id, publicKey: cards[0].public_key.public_key }; }); }).then(function(recipients) { var message = $('#chat-input').val(); var encryptedMessage = virgil.crypto.encryptStringToBase64(message, recipients); generalChannel.sendMessage(encryptedMessage); console.log(encryptedMessage); });
Зашифрованное сообщение имеет следующий вид:MIIDBQIBADCCAv4GCSqGSIb3DQEHA6CCAu8wggLrAgECMYICvDCCAVoCAQKgJgQkMDg3YjgwYmMtMzNjYi00MTI1LWI4YTgtYTE
3OTEwM2Y3ZjRkMBUGByqGSM49AgEGCisGAQQBl1UBBQEEggEUMIIBEAIBADBbMBUGByqGSM49AgEGCisGAQQBl1UBBQEDQgAEcd
8fhKqYlZxvcmmodg7Z3PNhE1LXLJqobouEcRfZaRMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAYBgcogYxxAgUCM
A0GCWCGSAFlAwQCAgUAMEEwDQYJYIZIAWUDBAICBQAEMEaJMAvX7S+52BpI5hYyFOc0noIc+qdFFrQanNAtNGBAX/Pxeg5yJ2iA
JijyZ8ut9zBRMB0GCWCGSAFlAwQBKgQQ81bklcNOyU/QTatCigSzoAQwHnAcbXk0daExIIS+sr6aIvVuF/o6j+1Rs5bvq2WVN41
k/Oir5x7KZTSR7v3nx+fTMIIBWgIBAqAmBCRmNzM4YTUwNi1hMDYwLTQ1MDgtYTJkYS04NjY1NjZlYzg0ODMwFQYHKoZIzj0CAQ
YKKwYBBAGXVQEFAQSCARQwggEQAgEAMFswFQYHKoZIzj0CAQYKKwYBBAGXVQEFAQNCAARJ5C3hsYuI2Sf14k60Dz5Mv5yD/AsVA
zPfsmlreGTC2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBgGByiBjHECBQIwDQYJYIZIAWUDBAICBQAwQTANBglg
hkgBZQMEAgIFAAQwhu7WM1rff9RYsQ+dmfX9Os3Irwm4cm5bIvUlcGXlCfmEsrjTyTg5MGjYLtxbYtL9MFEwHQYJYIZIAWUDBAE
qBBCfKdP/gZnkVwJvv4Hdf2eWBDC3czBjV/yPGeGTqBIilHSsrqwK7lVMTBuKR+mR3eNdh+yBIAcOk4rveSUbDuWagDIwJgYJKo
ZIhvcNAQcBMBkGCWCGSAFlAwQBLgQMfjkCvK3UgXdorcYUmtCHHuSm4yfBacMsniMADAeos7qN7OmNsFU1
При этом не стоит забывать, что несмотря на то, что речь в данной статье идет о текстовых сообщения, таким же образом вы сможете зашифровать любые бинарные данные: изображение, аудио или видео.
- Чтобы расшифровать адресованное ей сообщение, Алиса должна воспользоваться приватным ключом, который хранится только у нее:
// Прослушиваем канал и получаем новое сообщение generalChannel.on('messageAdded', function(message) { // Расшифровываем сообщение, используя Card Id и секретный ключ var decryptedMessage = virgil.crypto.decryptStringFromBase64( message.body, myCard.id, keyPair.privateKey ); console.log(message.author + ': ' + decryptedMessage); });
И получит текст сообщенияBob: Привет, Алиса!
Часть 3: заключительная
Как видите, создать IP мессенджер со встроенной функцией end-to-end шифрования достаточно просто. Разумеется, ваш мессенджер может быть написан на любом языке программирования и для любой платформы, при этом реализация шифрования всегда останется такой же простой.
Посмотреть демо версию мессенжера с возможностью создавать новые каналы и шифровать сообщения можно по ссылке.
Исходный код демо версии Virgil+Twilio IP мессенжера можно найти на GitHub.
Все наши тьюториалы по работе с Virgil Security под различными языками программирования доступны тут.
UPD
По просьбам трудящихся перечислим несколько вариантов использования описанного мессенджера:
- Встраивание системы мгновенных сообщение в ваше собственное приложение. Это позволит пользователям общаться без привлечения стороннего приложения.
- Добавление мессенджера на веб сайт для прямого общения со службой продаж или тех. поддержкой.
- Добавление мессенджера в любой инструмент используемый организацией(к примеру система документооборота). Это позволит избежать необходимости использовать дополнительные инструменты для общения внутри компании.