Шифрование платежной карты
В целях обеспечения безопасности данные платежной карты шифруются с использованием RSA PKCS1
Для шифрования необходимо:
Запрос GET https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key Запрос GET https://sandboxapi.tarlanpayments.kz/card/api/v1/encryption/public-key для получения publick_key с помощью которого шифруются данные карт используя алгоритм RSA PKCS1
Формируем JSON. Для приема денежных средств необходимы все данные карты:
{"pan":"4049121234345656","exp_month":"04","exp_year":"26","cvc":"123","full_name":"Test test"}
Для вывод денежных средств необходимы только pan карты:{"pan":"4049121234345656"}
Шифруем получившийся объект используя алгоритм RSA PKCS1 и публичный ключ
Получившийся шифр кодируем в base64
Пример ответа GET https://prapi.test-tarlanpayments.kz/card/api/v1/encryption/public-key
{
"status": true,
"message": "Success",
"result": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxTl2VCVIQ3R6WWexWfEt\n80+mwQLOwVRSsmmoFZhYnuCgtdthJlb4CJ+LTup19ttHdU0h43r3W4urNDWWFuxf\nlKsIuuztP4Zc44TV4gG7YkHmz+iP90JrYzhE4yMaMYv0jTJ1lXBGTHk+Sfoa2nGg\nIdB/onVGfX27W7yjv62yZ/7V/GZljxP/8V3x/KRm/i05B4hsSE3DWw2AX+dOtvSj\n/JYXu713nGh4lsj9/CABT/GHkwY33e14YwXAS4P7f/ixGdcFudKU1QxIorFqOK0W\nDURmfnnoBuL1ailkHWb8LIu7FXUEbKi0QpmKsV5UnFWNuIQKtE/Mt+P6UJ/oGtdc\nHQIDAQAB\n-----END PUBLIC KEY-----"
}
<?php
function encryptCard($pan) {
$panData = json_encode(['pan' => $pan]);
// Получаем публичный ключ
$response = file_get_contents('https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key');
if ($response === FALSE) {
throw new Exception('Can not get public key');
}
$responseJson = json_decode($response, true);
if (!isset($responseJson['result'])) {
throw new Exception('Invalid response format');
}
$publicKeyPem = $responseJson['result'];
// Декодируем публичный ключ из формата PEM
$publicKey = openssl_pkey_get_public($publicKeyPem);
if ($publicKey === FALSE) {
throw new Exception('Failed to parse public key');
}
// Шифруем данные с использованием публичного ключа
$encryptedCard = '';
if (!openssl_public_encrypt($panData, $encryptedCard, $publicKey)) {
throw new Exception('Failed to encrypt data');
}
// Возвращаем зашифрованную строку в формате base64
return base64_encode($encryptedCard);
}
try {
$pan = '4049121234345656'; // Пример PAN, который можно заменить на любой другой
$encryptedCard = encryptCard($pan);
echo "Encrypted Card: " . $encryptedCard . PHP_EOL;
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . PHP_EOL;
}
?>
import requests
import json
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKCS1_v1_5
from Crypto.Random import get_random_bytes
def encrypt_card(pan):
pan_data = json.dumps({'pan': pan}).encode('utf-8')
# Получаем публичный ключ
response = requests.get('https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key')
if response.status_code != 200:
raise Exception('Can not get public key')
response_json = response.json()
if 'result' not in response_json:
raise Exception('Invalid response format')
public_key_pem = response_json['result']
# Декодируем публичный ключ из формата PEM
public_key = RSA.import_key(public_key_pem)
# Шифруем данные с использованием публичного ключа
cipher = Cipher_PKCS1_v1_5.new(public_key)
encrypted_card = cipher.encrypt(pan_data)
# Возвращаем зашифрованную строку в формате base64
return base64.b64encode(encrypted_card).decode('utf-8')
try:
pan = '4049121234345656' # Пример PAN, который можно заменить на любой другой
encrypted_card = encrypt_card(pan)
print("Encrypted Card:", encrypted_card)
except Exception as e:
print("Error:", str(e))
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io"
"net/http"
)
func EncryptCard(pan string) (string, error) {
panData := struct {
Pan string `json:"pan"`
}{
Pan: pan,
}
response := struct {
PublicKey string `json:"result"`
}{}
notSortedJson, err := json.Marshal(panData)
if err != nil {
return "", err
}
publicKeyResp, err := http.Get("https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key")
if err != nil {
return "", err
}
defer publicKeyResp.Body.Close()
if publicKeyResp.StatusCode != http.StatusOK {
return "", errors.New("can not get public key")
}
readAll, err := io.ReadAll(publicKeyResp.Body)
if err != nil {
return "", err
}
err = json.Unmarshal(readAll, &response)
if err != nil {
return "", err
}
block, _ := pem.Decode([]byte(response.PublicKey))
if block == nil || block.Type != "PUBLIC KEY" {
return "", fmt.Errorf("failed to parse PEM block containing the public key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return "", fmt.Errorf("failed to parse public key: %v", err)
}
rsaPub, ok := pub.(*rsa.PublicKey)
if !ok {
return "", fmt.Errorf("not an RSA public key")
}
encryptedCard, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPub, notSortedJson)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(encryptedCard), nil
}
func main() {
pan := "4049121234345656" // Пример PAN, который можно заменить на любой другой
encryptedCard, err := EncryptCard(pan)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Encrypted Card:", encryptedCard)
}
Процедура ТестированиеEncryptCard()
// Пример PAN для тестирования
PAN = "4049121234345656";
// Вызов функции шифрования
Попытка
ЗашифрованнаяКарта = EncryptCard(PAN);
Сообщить("Зашифрованная карта: " + ЗашифрованнаяКарта);
Исключение
Сообщить("Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Процедура EncryptCard(PAN)
// Данные карты
ДанныеКарты = Новый Структура;
ДанныеКарты.Вставить("pan", PAN);
// Преобразование данных карты в JSON
JSONСтрока = ПреобразованиеВJSON(ДанныеКарты);
// Получение публичного ключа
Запрос = Новый HTTPЗапрос("https://prapi.tarlanpayments.kz/card/api/v1/encryption/public-key");
HTTPСоединение = Новый HTTPСоединение("prapi.tarlanpayments.kz");
Ответ = HTTPСоединение.Получить(Запрос);
Если Ответ.КодСостояния <> 200 Тогда
Сообщить("Ошибка получения публичного ключа: " + Ответ.КодСостояния);
Возврат "";
КонецЕсли;
// Чтение тела ответа
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
Декодер = Новый JSONДекодер;
ОтветJSON = Декодер.ПрочитатьJSON(ТелоОтвета);
ПубличныйКлючСтрока = ОтветJSON.result;
// Декодирование PEM и извлечение публичного ключа
ПубличныйКлючБайты = КодировкаBase64.СтрокаВБайты(ПубличныйКлючСтрока);
ПубличныйКлючPEM = ПолучитьPEM(ПубличныйКлючБайты);
// Шифрование данных карты
ЗашифрованнаяКарта = ШифрованиеRSA(ПубличныйКлючPEM, JSONСтрока);
// Кодирование зашифрованных данных в Base64
ЗашифрованнаяКартаBase64 = КодировкаBase64.СтрокаИзБайтов(ЗашифрованнаяКарта);
Возврат ЗашифрованнаяКартаBase64;
КонецПроцедуры
Функция ПреобразованиеВJSON(Данные)
JSONЗапись = Новый ЗаписьJSON;
JSONЗапись.УстановитьСтроку();
JSONЗапись.ЗаписатьЗначение(Данные);
Возврат JSONЗапись.Закрыть();
КонецФункции
Функция ПолучитьPEM(ПубличныйКлючБайты)
ОткрытыйКлюч = Новый ОткрытыйКлючШифрования;
ОткрытыйКлюч.Установить(ПубличныйКлючБайты);
Возврат ОткрытыйКлюч;
КонецФункции
Функция ШифрованиеRSA(ОткрытыйКлюч, Данные)
Результат = Новый Массив;
Для Каждого Байт Из ОткрытыйКлюч.Шифровать(Данные, "RSA/ECB/PKCS1Padding") Цикл
Результат.Добавить(Байт);
КонецЦикла;
Возврат Результат;
КонецФункции
Last updated