Сохранение данных банковской/кредитной карты, как в приложении AliExpress /Yota /сбербанк_онлайн

205
12 марта 2022, 12:50

Суть такая: в приложении AliExpress есть возможность добавить данные банковской карточки и дальше с него автоматически производить оплату.

Каким образом реализуется сам алгоритм?

Каким образом мы можем сохранить данные карты в приложении, или это не в приложении сохраняется, а отправляется на сервер?

Если отправляется на сервер, то наверное, с шифрованием? То есть сам алгоритм работы при вот таком действии, с кодом сам уже попробую реализовать.

Приложении AliExpress взял, как пример, так как с этим в нём и сталкивался

Answer 1

Хранить данные банковских карт в приложении Вы не имеете права по закону. Хранить эти данные на сервере Вы можете если имеете сертификат PCI DSS (для начала ссылка в википедии), получить который очень не просто и стоит это не малых денег. Единственный, простой, вариант - это использовать платежный системы к примеру Яндекс.Касса и тому подобные (ссылка на рейтинг). Большинство этих систем поддерживает рекуррентные платежи, т.е. данные карты хранит сама система и дальнейшие платежи (к примеру по подписке), делает автоматически по вашему запросу, без дополнительных действий со стороны пользователя.

Answer 2

За хранение карточек без прохождение PCI DSS с вами совершат действия сексуального-насильственного характера.

Пока я видел 2 метода - оба хранят данные в компании эквайринге. (aliexpress использует эквайринг alipay):

  1. Виртуальные счета - вы создаете виртуального пользователя в платежной системе. Связываете его со своим аккаунтом и выставляете ему счета. Например так делает monetka.ru (она же payanyway ). Пример документации https://payanyway.ru/info/p/ru/public/merchants/SDKphp.pdf стр 16 "Создание нового пользователя"
  2. Хранение виртуальных карт - по сути то же самое. Встречал у альфабанка. Но вы видите конкретную карту, часть информации скрыта. Пользователь через сервис привязывает карточку, вы видите "виртульную" карту или список карт и привязываете к его аккаунту. Потом при оплате даете ему выбор карты и подтверждение оплаты.

Это называется подписки, рекурентные платежи или регулярные платежи. Можете пройти по платежным система и посмотреть как у них реализовано.

Answer 3

Не знаю кейса с отправкой инфы о карте на сервер - это как-то совсем не секьюрно и получается какой-то сбор карт.

Все строго шифровать!

Тут либо карту шифровать по пину/паролю - очень хорошая статья по этой теме.

Либо использовать SQLCipher - читать тут.

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

Answer 4

Хранить такие данные на телефоне небезопасно. Если все таки есть желание хранить, то можно использовать 3D шифрование(TripleDES)

Вот пример:

 public class TripleDESHelper {
private Context mContext;
public TripleDESHelper(Context context) {
    mContext = context;
}
public String encrypt(String message) throws Exception {
    final MessageDigest md = MessageDigest.getInstance("md5");
    final byte[] digestOfPassword = md.digest("H3423G583424232CR9"
            .getBytes("utf-8"));
    final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    for (int j = 0, k = 16; j < 8; ) {
        keyBytes[k++] = keyBytes[j++];
    }
    final SecretKey key = new SecretKeySpec(keyBytes, getString(mContext.getContentResolver(),
            Secure.ANDROID_ID));
    final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, key, iv);
    final byte[] plainTextBytes = message.getBytes("utf-8");
    final byte[] cipherText = cipher.doFinal(plainTextBytes);
    return Base64.encodeToString(cipherText, Base64.NO_WRAP);
}
public String decrypt(String message) throws Exception {
    final MessageDigest md = MessageDigest.getInstance("md5");
    final byte[] digestOfPassword = md.digest("H3423G583424232CR9"
            .getBytes("utf-8"));
    final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    for (int j = 0, k = 16; j < 8; ) {
        keyBytes[k++] = keyBytes[j++];
    }
    final SecretKey key = new SecretKeySpec(keyBytes, getString(mContext.getContentResolver(),
            Secure.ANDROID_ID));
    final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    decipher.init(Cipher.DECRYPT_MODE, key, iv);
    final byte[] encData = Base64.decode(message, Base64.NO_WRAP);
    final byte[] plainText = decipher.doFinal(encData);
    Log.d(getClass().getSimpleName(),new String(plainText, "UTF-8"));
    return new String(plainText, "UTF-8");
}
}

Лучше всего передавать данные на сервер по HTTPS и при этом еще и шифровать алгоритмом 4-х рукопожатий. Асимметричные алгоритмы (RSA, El-Gamal)

Answer 5

Я бы действовал так:

  1. По https на сервер бы отправлял все данные карты(номер, срок действия, CVC).
  2. На сервере использовал бы Stripe, чтобы привязять карту к конкретному юзеру. Stripe сам берет на себя вс нагрузку по защищенному хранению и использованию карты.
  3. На сервере бы хранил только идентификаторы карт, которые сформировал Stripe.
  4. Локально бы хранил только мета информацию(последние 4 цыфры и тд.)
READ ALSO
Исчезла первая буква в имени подключаемого файла

Исчезла первая буква в имени подключаемого файла

При попытке подключения файла RouteControllerphp на сайте появляется ошибка "Неверное имя файла для подключения - outeController"

81
Вывод переменной в документ

Вывод переменной в документ

Ребят, помогите с JS Почему в этом случае не работает вывод переменной? Нигде не могу найти документаций, но видел пример использования

159
Помогите решить задачу c мультизагрузкой файлов с progress bar

Помогите решить задачу c мультизагрузкой файлов с progress bar

Как можно сделать эту конструкцию на javascript?

82