Привет, Хабр!
Несмотря на набирающие все большую популярность мобильные мессенджеры, такие как WhatsApp и Telegram, старые добрые SMS все еще не теряют свою актуальность. SMS можно использовать для отправки разного рода уведомлений, для двухфакторной аутентификации или при сбросе пароля. Однако последние успешные атаки на мобильные сети заставляют задуматься о дополнительном уровне защиты передаваемых с помощью SMS данных.
В этой статье мы поговорим о том, как используя сервисы Virgil и Twilio, сделать процесс отправки SMS на Android устройства безопасным.

Прежде чем приступать к программированию в очередной раз напомним о ряде предварительных действий.
Для отправки SMS мы будем использовать Twilio API, для доступа к которому необходимо создать Twilio аккаунт тут. После регистрации вы получите специальные идентификаторы, необходимые для работы с API — TWILIO_ACCOUNT_SID и TWILIO_AUTH_TOKEN.

Чтобы зашифровать SMS сообщения нам потребуется помощь Virgil Crypto Library и Virgil Keys Service, для доступа к которому необходимо создать Virgil аккаунт и сгенерировать специальный токен VIRGIL_ACCESS_TOKEN.

После выполнения вышеперечисленных шагов можно приступать к реализации SMS уведомлений.
Сервисы Virgil имеют большой набор SDK, позволяющих работать с ними практически на любом популярном языке программирования. В предыдущих статьях мы показывали как работать с сервисами с помощью JavaScript. Сегодня, в качестве разнообразия, мы покодим на C#.

Распишем процесс отправки и получения зашифрованных SMS поэтапно.

  1. Устанавливаем Virgil и Twilio SDK, используя менеджер пакетов NuGet:

    PM> Install-Package Virgil.SDK
    PM> Install-Package Twilio

  2. Инициализируем клиенты для работы с Virgil и Twilio API:

    // указываем идентификаторы Twilio аккаунта
    string accountSid = "%TWILIO_ACCOUNT_SID%";
    string authToken = "%TWILIO_AUTH_TOKEN%";
    // инициализируем Twilio API клиент
    var twilio = new TwilioRestClient(accountSid, authToken);
    // инициализируем Virgil клиент, используя секретный токен
    var virgil = ServiceHub.Create("%VIRGIL_ACCESS_TOKEN%");
    

    Обратите внимание на переменные accountSid и authToken. В них мы указываем идентификаторы нашего Twilio аккаунта, которые можно найти здесь.

  3. Реализуем отправку зашифрованных сообщений с помощью обычного POST запроса к сервису Twilio (отсылаем приглашения с паролями для входа на вечеринку):

    // Подготовим список получателей SMS сообщений
    var people = new Dictionary<string,string>() {
        {"+14XXXXXXXX1","Darth Vader"},
        {"+14XXXXXXXX2","Luke Skywalker"},
        {"+14XXXXXXXX3","Princess Leia"}
    };
    
    // загрузим публичные ключи получателей с Virgil Keys Service
    var peopleCards = await Task.WhenAll(people
        .Select(it => virgil.Cards.Search(number)));
    
    foreach (var personCards in peopleCards)
    {
        // оставим карты получателей, созданные последними
        var personCard = personCards.OrderBy(it => it.CreatedAt).Last();
        var personName = people[personCard.Identity.Value];
    
        // инстанциируем класс, который используется для шифрования данных и разбиения 
        // результирующего массива в пакеты указанной длинны (в байтах).
        using (var tinyCipher = new VirgilTinyCipher(120))
        {
            var message = $"Hey {personName}, your security word is STAR. We are waiting for you!";
            var messageData = Encoding.UTF8.GetBytes(message);
    
            tinyCipher.Encrypt(messageData, personCard.PublicKey.Value);
    
            // отправляем пакеты получателю, с учетом того, что размер одного SMS сообщения 
            // равен 160-ти символам (120 байт в base64 формате).
            for(int index = 0; index < tinyCipher.GetPackageCount(); index++)
            {
                var encryptedMessage = Convert.ToBase64String(tinyCipher.GetPackage(index));
    
                // Отправим зашифрованное сообщение с помощью Twilio API
                twilio.SendMessage(
                    SMS.Constants.TwilioPhoneNumber, // Номер отправитель, номер Twilio с включенными SMS
                    personCard.Identity.Value,       // Номер получателя сообщения
                    encryptedMessage);
            }
        }
    }
    

  4. Расшифровываем сообщение на стороне получателя. Чтобы получить SMS воспользуемся Android SMS API. Для расшифровки сообщения нам также потребуется Virgil SDK для .NET:

    // инстанциируем класс, используя все тот же размер пакета в 120 байт.
    var tinyCipher = new VirgilTinyCipher(120);
    
    //расшифровываем сообщение message используя приватный ключ
    private void OnSmsReceived(string from, string message)
    {
        // добавляем пакеты в инстанс класса, до тех пор пока не соберем 
        // все пакеты, которые были посланы в отдельных сообщениях.
        this.tinyCipher.AddPackage(Convert.FromBase64String(message));
        if (this.tinyCipher.IsPackagesAccumulated())
        {
            var decryptedData = this.tinyCipher.Decrypt(this.myPrivateKey);
            var decryptedMessage = Encoding.UTF8.GetString(decryptedData, 0, decryptedData.Length);
    
            this.tinyCipher.Reset();
    
            Application.Current.MainPage.DisplayAlert($"From: {from}", decryptedMessage, "Got It");
        }
    }
    


Как видите с Twilio и Virgil API отправка и получение зашифрованных SMS становится простой задачей, не требующей глубоких знаний в области криптографии.

P.S.


Скачать исходный код, реализующий отпраку зашифрованных SMS, вы можете на GitHub.
Поделиться с друзьями
-->

Комментарии (12)


  1. Kioju
    28.06.2016 21:51

    Немного не по теме, но задела строчка «старые добрые SMS все еще не теряют свою актуальность».

    SMS очень дорогие сейчас. Намного дешевле звонить IVR-роботом. А идеальный вариант — пуши или сообщения в мессенджерах.

    З.Ы. Есть WEB-api у Virgil и турториал по нему?


    1. dmitry_ch
      29.06.2016 09:16

      Операторы, внезапно понявшие, что юзеры нашли и другие неплохие средства звонить и писать друг другу, помимо дорогих минут и жутко дорогих СМС, начали упаковывать самое привлекательное (передачу данных) в комплект с пакетами минут и СМС (чуть не в нагрузку, получается). В результате, если человек покупает пакет на хотя бы 3-4 Гб трафика, у него внезапно оказывается «совершенно бесплатно, т.к. даром» (на самом деле, по бросовой «пакетной цене») штук 300-400 СМС-ок, из которых средний юзер использует в месяц штук 10.

      Так что дороговизна СМС — штука относительная. Если поштучно, то совести у операторов нет. Если пакетом — то «столько не нужно», и они вроде как бесплатны и в нагрузку.


    1. denzzel
      29.06.2016 10:25

      Вопрос не в том на сколько дорогие SMS сейчас, вопрос больше в том на сколько безопастным является их передача через сети GSM. На сегодняшний день уязвимости в GSM сетях дают возможность злоумышленникам совершать перехват SMS сообщений, голосовых звонков и т.д. Это связанно с тем что методы защиты в GSM разрабатывались еще в 90-е годы и до сих пор они не обновлялись.

      Передача SMS сообщений испрользуются не только в рамках мобильных телефонов для общения с друзьями. Но и в различных устройствах, где установлен GSM модуль для дистанционного управления (к примеру Управление нагрузками). В таких устройствах вопрос безопастности очень актуален.

      З.Ы. Есть WEB-api у Virgil и турториал по нему?


      Нет в качестве sms-шлюза используется Twilio, в статье показан лишь пример как это можно сделать с помощью Twilio. Но в целом Virgil можно интегрировать c любым API.


  1. kx13
    29.06.2016 09:20

    Сейчас СМС, можно сказать, бесплатно на многих пакетных тарифных планах, так как несколько сотен СМС идут вместе с другими услугами в одном пакете.
    Например на тарфифах Smart от МТС (специально сделаным для смартфонов) дают от 200 до 1100 СМС.

    Поэтому можно считать, что для пользователей смартфонов, СМС зачастую не оплачиваются отдельно.


  1. DarkOrion
    29.06.2016 10:25
    +2

    А Twillo здесь просто в качестве примера sms-шлюза? А то он как-то вообще полезной нагрузки не несет, все делает библиотека Virgil.


    1. denzzel
      29.06.2016 10:27

      Все правельно, Twilio используется в качестве примера.


  1. nikitasius
    29.06.2016 10:40

    В Европе СМС не стоят ничего. Все нормальные тарифы (например 3 евро в месяц) идут с безлимитными СМС.


    1. Tangeman
      29.06.2016 21:30

      Европа большая, и не везде они «не стоят ничего». В Германии, к примеру, чтобы получить sms-flat, придётся выкладывать ежемесячно около 4,5 евро минимум, и то с контрактом на два года, а без контракта меньше 8 евро не получится. В то же время, за те же 4-5 евро, можно взять почти любой Internet пакет (100 MB — это больше чем нужно для передачи 200 тыс. смс) — и без контракта.

      Если человеку нужен телефон не только для сообщений, то цены уже резко меняются в бОльшую сторону — за 4 евро не будет ни нормального руминга (или будет по диким ценам), ни нормальных цен для международных звонков (все дискаунтеры расчитаны на национальную связь, в основном).

      Но самая большая проблема с SMS, впрочем — нет никакой (официальной) гарантии доставки и даже гарантии уведомления о доставке или её невозможности.

      Вторая большая проблема — хотя смс и можно шифровать, но всё равно оператор знает кто кому шлёт, в отличие от мессенжеров. Хотя, с другой стороны, честных людей это волновать не должно, разве что они опасаются коммерческого или промшпионажа.

      Так что не всё так просто как кажется. Ну а что касается России — то если известный пакет законов будет принят — то можно попрощаться с шифрованием SMS, равно как и со всем остальным.


      1. nikitasius
        29.06.2016 21:52

        Во Франции 2 часа блабла и анлим СМС у free.fr стоит 2€, а если вы абонент free (инет), то за мобилку платите 0. MMS кстати тоже, безлимитные.
        Как плюшки — бесплатные звонки на стационарники во многих странах мира, в том числе и Россию, на мобильники же 0.22€ за минуту. Международные ММС полевро вроде за штуку, СМС не проверял.


  1. Kioju
    30.06.2016 22:57

    А можно как непрофессионалу в части криптографии объяснить на пальцах — чем хуже обычное шифрование, всякие там SHA1, HMAC-SHA, MD5, Base64, AES, DES, 3DES?

    Опять же — не по теме статьи, — я имел в виду не смс у пользователя, а рассылка смс от компании. Мы отсылаем десятки миллионов смс в месяц. И докатились до того, что дешевле звонить чем слать смс потому что операторы оборзели поднимать и поднимать цены как раз на такие рассылки.

    И это оборзение заставляет массово уезжать в всякие менеджеры вроде Sender или Telegram


    1. sseroshtan
      01.07.2016 15:07
      +2

      Не все из перечисленных алгоритмов являются алгоритмами шифрования, а именно:


      • MD5, SHA1, SHA256,… — алгоритмы хеширования, задачей которых является преобразование массива входных данных произвольной длины в (выходную) битовую строку фиксированной длины, то есть в этом случае, получается некий "отпечаток пальца" для входных данных [wiki], и нет возможности сделать обратное преобразование.


      • HMAC — алгоритмы создания кода проверки подлинности сообщений, использующие алгоримы хеширования [wiki], в этих алгоритмах задействован секретный ключ.


      • base64 — алгоритм позволяющий представить любую байтовую последовательность в виде печатный символов ASCII, и наоборот.


      • AES, DES, 3DES — вот это как раз алгоритмы шифрования! они принадлежат к группе симметричных алгоритмов шифрования, то есть для шифрование и расшифровки используется один и тот же секретный ключ — что не дает возможность его распространения по открытому (незащищенному) каналу!


      • RSA, ECIES — алгоритмы асимметричного шифрования. Данные алгоритмы используют пару ключей: открытый ключ и закрытый ключ. Открытый ключ используется для операций шифрования и проверки подписи, и может распространятся в открытом виде по незащищенным каналам. Закрытый ключ используется для операций расшифровки и создания подписи, и хранится только и владельца.

      VirgilSecurity в своей основе использует гибридное шифрование — асимметричное(ECIES) + симметричное(AES256). При таком подходе возникает необходимость в удобном распространении открытых ключей, чем и занимается Virgil Keys Service.


      1. Kioju
        03.07.2016 23:21

        Всё, до меня наконец-то дошло. Спасибо!

        Нужно было просто ещё раз прочесть, что фишка в асимметричном шифровании.