Відправляємо зашифровані SMS повідомлення з Virgil


Привіт, Хабр!
Незважаючи на що набирають все більшу популярність мобільні месенджери, такі як 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.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.