Pull to refresh
0
Virgil Security, Inc.
Мы превращаем программистов в криптографов.

Создаем безопасный IP мессенджер с помощью Virgil и Twilio за 30 минут

Reading time 7 min
Views 20K

Привет!
Мы уже показывали вам код, с помощью которого можно легко и просто реализовать end-to-end шифрование. Давайте пойдем дальше и, используя сервисы Virgil Security, разработаем безопасный IP мессенджер. Реализация безопасного IP мессенджера со встроенной функцией шифрования – задача далеко не тривиальная. В этой статье мы хотим рассказать как, используя Virgil API и Тwilio IP Messaging API, сделать этот процесс намного проще.

Часть 1: подготовительная


Прежде чем приступать к реализации нашего мессенджера необходимо выполнить пару предварительных действий:

  1. Создать аккаунт Twilio. Twilio — компания, предоставляющая в качестве сервиса средства коммуникации. С помощью Twilio задача разработки IP мессенджера сильно упрощается. Однако в этой статье наша цель гораздо более амбициозная. Напоминаем, что нам требуется безопасный(не путайте с анонимным) IP мессенджер с функцией end-to-end шифрования. Поэтому нам потребуется…

  2. Создать аккаунт Virgil Security. Аккаунт открывает возможность зарегистрировать приложение и получить VIRGIL_ACCESS_TOKEN — секретный ключ, позволяющий пользоваться сервисами Virgil Security.

После выполнения вышеперечисленных шагов вы станете счастливым обладателем следующего набора параметров:
  1. TWILIO_ACCOUNT_SID — идентификатор вашего аккаунта Twilio (доступен в вашем аккаунте).
  2. TWILIO_API_KEY — секретный ключ, используемый для аутентификации(сгенерировать его можно здесь).
  3. TWILIO_API_SECRET — дополнительная секретная информация, необходимая для аутентификации(создается тут).
  4. TWILIO_IPM_SERVICE_SID — экземпляр службы Twilio, в котором хранятся все данные о вашем приложении(создать можно по ссылке).
  5. VIRGIL_ACCESS_TOKEN — уникальный маркер, позволяющий получить доступ к Virgil Security API. Каждый запрос к API должен содержать VIRGIL_ACCESS_TOKEN. Получить его можно после создания Virgil приложения тут.
  6. VIRGIL_APP_PRIVATE_KEY — секретный ключ вашего Virgil приложения. Используется для создания validation token для аутентификации публичных ключей ваших пользователей в случае, если использование Identity Service нежелательно. Секретный ключ генерируется на вашем компьютере на странице вашего приложения после входа на сайт Virgil.
  7. 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 на предварительном этапе, переходим непосредственно к разработке.
Наш мессенджер будет иметь клиент серверную структуру. Но все самое интересное(шифрование, отправление и расшифровка сообщений) будет происходит на стороне клиента, на ней мы и сосредоточим большую часть нашего внимания.

  1. Подключаем 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>
    

  2. Инициализируем работу с сервисами(токены для работы с API получаем от сервера):

    // Инициализация Twilio
    var accessManager = new Twilio.AccessManager('%TWILIO_TOKEN%');
    var messagingClient = new Twilio.IPMessaging.Client(accessManager);
    // Инициализация Virgil
    var virgil = new VirgilSDK("%VIRGIL_ACCESS_TOKEN%");
    

  3. С помощью 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-----
    

  4. Для того чтобы другие участники переписки могли отправлять Алисе зашифрованные сообщения, её публичный ключ должен быть размещен в хранилище ключей 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"
       }
    }
    

  5. Теперь пользователь Алиса готов к безопасному общению. Создадим для этого канал 'general':

    // Создаем новый канал
    twilioClient.createChannel({ friendlyName: 'general' }).then(function(channel) {
        generalChannel = channel;
    });
    

  6. Любой желающий способен зайти в канал '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

    При этом не стоит забывать, что несмотря на то, что речь в данной статье идет о текстовых сообщения, таким же образом вы сможете зашифровать любые бинарные данные: изображение, аудио или видео.

  7. Чтобы расшифровать адресованное ей сообщение, Алиса должна воспользоваться приватным ключом, который хранится только у нее:

    // Прослушиваем канал и получаем новое сообщение
    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
По просьбам трудящихся перечислим несколько вариантов использования описанного мессенджера:
  1. Встраивание системы мгновенных сообщение в ваше собственное приложение. Это позволит пользователям общаться без привлечения стороннего приложения.

  2. Добавление мессенджера на веб сайт для прямого общения со службой продаж или тех. поддержкой.

  3. Добавление мессенджера в любой инструмент используемый организацией(к примеру система документооборота). Это позволит избежать необходимости использовать дополнительные инструменты для общения внутри компании.

Tags:
Hubs:
+8
Comments 10
Comments Comments 10

Articles

Information

Website
virgilsecurity.com
Registered
Founded
2014
Employees
31–50 employees
Location
Украина