Ошибка расшифровки Visa Test Card с использованием RSA

Я работаю над созданием приложения для устройства чтения смарт-карт, используя набор тестов Visa на языке Си. Читая карточку № 2, я получаю следующий сертификат открытого ключа эмитента после прочтения карточки:

uint8_t ISSUER_PK_CERTIFICATE[] = {41 03 b1 61 f7 dd 14 34 85 79 1b f6 01 04 ea 10 08 06 9d 16 b6 c3 b3 5b 4e 37 ed 20 25 66 d8 77 6f 48 02 28 32 0a 90 31 ae 28 28 75 fa 1b 3a bf c7 6d 15 6f f4 b5 08 4a fd 9c b0 ef b0 8a 8e 5b 41 fa be 99 3b 04 fe 1b 76 8d ef b6 eb ae d1 77 4d d0 5e 7f f7 0c 45 86 42 85 e6 d0 06 2d 86 65 4e 7a 88 5f 49 f9 f3 11 9f 24 35 18 4c 28 1c 14 93 d2 ac 69 ec c7 88 da c0 75 9a 73 ec d5 f0 28 b3 27 a1 e5 1d c5 cb 43 53 7b 1d 2a a7 04 62 cd a3 c8 74 a5 7c 45 8e 52 15 09 ff 98 73 71 d6 da 8d 7a 4f f5 6f 10 87 89 68 86 33 17 1e f1 d6 9d},

... (игнорируя особенности форматирования в массивах C), где модуль равен 176, а из Visa у меня есть следующий модуль открытого ключа CA. Карты являются тестовыми картами, поэтому у меня нет проблем с общим выводом:

uint8_t VISA_PK_MODULUS[] = {99 6A F5 6F 56 91 87 D0 92 93 C1 48 10 45 0E D8 EE 33 57 39 7B 18 A2 45 8E FA A9 2D A3 B6 DF 65 14 EC 06 01 95 31 8F D4 3B E9 B8 F0 CC 66 9E 3F 84 40 57 CB DD F8 BD A1 91 BB 64 47 3B C8 DC 9A 73 0D B8 F6 B4 ED E3 92 41 86 FF D9 B8 C7 73 57 89 C2 3A 36 BA 0B 8A F6 53 72 EB 57 EA 5D 89 E7 D1 4E 9C 7B 6B 55 74 60 F1 08 85 DA 16 AC 92 3F 15 AF 37 58 F0 F0 3E BD 3C 5C 2C 94 9C BA 30 6D B4 4E 6A 2C 07 6C 5F 67 E2 81 D7 EF 56 78 5D C4 D7 59 45 E4 91 F0 19 18 80 0A 9E 2D C6 6F 60 08 05 66 CE 0D AF 8D 17 EA D4 6A D8 E3 0A 24 7C 9F},

также игнорируя форматирование (я написал это здесь для простоты), где модуль также равен 176. Индекс открытого ключа CA равен 5, а показатель степени равен 3, вот как я получил вышеуказанный ключ. Теперь я написал следующую функцию для реализации алгоритма расшифровки RSA, чтобы иметь возможность проверить подпись сертификата:

uint32_t buffer[ISSUER_PK_CERTIFICATE_LENGTH]; //this holds the "decrypted" data

void decryptCertificate(uint8_t exponent)
{
    uint32_t buffer[ISSUER_PK_CERTIFICATE_LENGTH]; //the length is in hex

    for(int i = 0; i < hexToDecimal(ISSUER_PK_CERTIFICATE_LENGTH); i++) //conversion to integer for my convenience
    {
        uint32_t powered = pow(ISSUER_PK_CERTIFICATE[i], exponent);
        uint32_t remainder = powered / VISA_PK_MODULUS[i];
        uint32_t multiplied = remainder * VISA_PK_MODULUS[i];
        uint32_t original = powered - multiplied;

        buffer[i] = original;
    }
}

но окончательный "расшифрованный" массив не соответствует требованиям проверочного теста, определенного VISA. Кто-нибудь видит, где я мог ошибиться при реализации вышеупомянутого алгоритма, или кто-то может указать мне правильное направление, если я ошибся? вывод дешифрования выглядит так:

8f  1b  94  1f  2d  3d  23  00  8b  40  be  00  01  40  06  d0  24  0c  2e  2e  5c  03  35  16  82  7d  5c  08  7b  94  67  4b  0b  84  02  00  8a  14  01  c9  20  9e  98  5d  1c  63  8c  08  43  35  27  14  0c  3d  86  94  61  81  4c  27  3a  48  d0  31  05  01  20  3f  b3  40  a1  77  1b  4b  ef  5b  ab  60  36  38  31  1c  18  01  3d  01  45  e0  43  13  6e  43  d8  4e  6e  29  7a  08  70  41  48  27  37  11  28  00  32  5a  0a  10  34  3e  00  00  0d  49  b0  c7  36  08  30  4d  00  1b  08  99  00  11  b3  27  3d  19  01  35  0c  03  07  2a  5e  ed  2f  40  20  8d  02  39  2f  45  13  bd  0d  10  2d  09  41  08  25  08  58  00  01  2c  51  05  06  07  13  a1  cc  0a  1b  88  00  01  04  97

Примечание: спецификация Visa гласит, что функция восстановления имеет вид: X = Recover (PK) [S] = Se mod n с цифровой подписью S и открытым ключом PK.

2 ответа

Решение

Похоже, что вы пытаетесь выполнить расшифровку RSA для каждого байта в отдельности. Это неверно - каждый массив сертификатов и модулей представляет одно большое целое число. Вам потребуется использовать математическую библиотеку с большими целыми числами (или специализированную криптографическую библиотеку) для выполнения этой расшифровки.

В качестве общего комментария OpenSSL может подойти вам. Если его размер служебной информации или размер библиотеки слишком велик для устройства чтения карт, существуют другие библиотеки, специально предназначенные для сред встроенных устройств. Посмотрите модули крипто-библиотек в вики ( Crypto Libraries), и среди них CyaSSL, MatrixSSL, PolarSSL и SharkSSL, как известно, для встроенных устройств.

Другие вопросы по тегам