LINUX.ORG.RU

Простой алгоритм шифрования


0

0

Добрый вечер!

Подскажите, пожалуйста, простой алгоритм шифрования с открытым ключом. Задача заключается вот в чем. Необходимо зашифровать строчку (длиной 30 байт) с помощью закрытого ключа, а расшифровать с помощью открытого ключа. Т.е. стандартная схема. Проблема в том, что расшифровку необходимо встроить в программу, так чтобы она не зависела от внешних библиотек (gnupg, openssl). Особо жестких требований к криптостойкости нет (скорее защита от дурака, но можно чуть по сложнее). Требований по быстродействию так же нет.

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

★★

Ответ на: комментарий от CyberTribe

Это очевидный ответ. Но ради зашифровать 30 байт и статически линковать такого монстра. Как-то не охота.

olegk ★★
() автор топика
Ответ на: комментарий от olegk

Расковырять код и взять какой-нибудь алгоритм оттуда?

CyberTribe ★★
()

>Задача заключается вот в чем. Необходимо зашифровать строчку (длиной 30 байт) с помощью закрытого ключа, а расшифровать с помощью открытого ключа. Т.е. стандартная схема.

Что?

anonymous
()
Ответ на: комментарий от Zitzy

Плюсую за Эль-Гамаля. В свое время реализовывал схему ЭЦП на нем, объем кода выработки подписи ~80 строк, проверки подписи — ~100 строк. Для работы с большими числами использовал библиотеку imath (гуглить по «Arbitrary precision integer arithmetic routines.», апстрим страничка похоже умерла). Библиотека представляет собой единственный исходник на C объемом в ~3300 строк (тут уж ничего не поделаешь, но ничего компактней на тот момент не нашел).

Deleted
()

>Требований по быстродействию так же нет

Ну раз так...

Перемножать каждый байт на n*pi байт из /dev/urandom

Правда для расшифровки придется собрать квантовик 3-его поколения.

anonymous
()
Ответ на: комментарий от anonymous

студент пишет курсовую работу?


Ошибаешься. Я уже давно не студент.

olegk ★★
() автор топика
Ответ на: комментарий от Deleted

Плюсую за Эль-Гамаля. В свое время реализовывал схему ЭЦП на нем, объем кода выработки подписи ~80 строк, проверки подписи — ~100 строк. Для работы с большими числами использовал библиотеку imath (гуглить по «Arbitrary precision integer arithmetic routines.», апстрим страничка похоже умерла). Библиотека представляет собой единственный исходник на C объемом в ~3300 строк (тут уж ничего не поделаешь, но ничего компактней на тот момент не нашел).


Буду разбираться. Если получится, то выложу здесь пример (для тех кому надо будет для старта).

olegk ★★
() автор топика

Если нужно что-то действительно простое - смотри в сторону поточных шифров, например RC-4, пишется на коленке за полчаса.

MuZHiK-2 ★★★★
()

По наростанию продвинутости: Шифр Шамира Шифр Эль-Гамаля Шифр RSA

Эти шифры хорошо описаны в книге Рябко, Фионов Криптографические методы защиты информации. Книгу можно найти в интернете. Если нужно у меня есть код всех трёх шифров, правда на perl.

Olegymous ★★★
()
Ответ на: комментарий от Olegymous

+1, сам у них учился, разжёвано всё от и до. Курсовик был написан без проблем, как раз то, что у ТС он и делал (правда три или четыре алгоритма было использовани).

Hokum ☆☆☆☆
()

>Необходимо зашифровать строчку (длиной 30 байт) с помощью закрытого ключа, а расшифровать с помощью открытого ключа. Т.е. стандартная схема

Я уже давно не студент.
стандартная схема

и так ничему и не научился. стандартная схема - шифровать открытым ключом получателя. та схема, которую ты описал используется для генерации/проверки ЭЦП.

anonymous
()
Ответ на: комментарий от anonymous

>Необходимо зашифровать строчку (длиной 30 байт) с помощью закрытого ключа, а расшифровать с помощью открытого ключа. Т.е. стандартная схема

Я уже давно не студент.

стандартная схема


и так ничему и не научился.
стандартная схема - шифровать открытым ключом получателя.
та схема, которую ты описал используется для генерации/проверки ЭЦП.

anonymous
()

Лучше делай с SSL. Геммороя в противном случае будет больше чем профита. Ведь в любом случае придется реализовывать работу с большими числами :] Плюс следует понимать, что в случае самопала, кроме тебя твой говнорезультат больше никто не расшифрует. Впрочем, можешь и реализовать. Что там того RSA? a**b = c (mod p). Но важно понимать, что стойкость этого решения будет отличаться от заявленной.

Впрочем, если все равно очень хочется - google FIPS 186-3

vasily_pupkin ★★★★★
()
Ответ на: комментарий от anonymous

RSA - алгоритм с восстановлением. Так что почему бы и нет? 30 байт - 240 бит, это просто понт, в модуль влезает.

vasily_pupkin ★★★★★
()
Ответ на: комментарий от anonymous

А. Я как то не заметил что ТС хочет шифроваться на закрытом. Но и это тоже возможно (с определенными условиями ессн) — можно взять ECPV. Правда, тогда открытый ключ не стоит употреблять как открытый :D

vasily_pupkin ★★★★★
()

Ну раз 30 байт то может xor подойдет ? ;)

Пароль xor текст = зашифрованное сообщение.

Главное постараться чтобы пароль был по длине как текст и еще случайным.

OxiD ★★★★
()
Ответ на: комментарий от Deleted

Спасибо за подсказку по библиотеки imath (очень компактно). Алгоритм выбрал RSA, так как достаточно проще для моего восприятия. Выкладываю версию (пока еще не полноценную), но может кому-то пригодится.

/**
\param n - public key
\param e - public key
\param input - input buffer (length 30)
\param output - output buffer (length 32)
*/
void encrypt(mp_int n, mp_int e, unsigned char *input, unsigned char *output)
{
   mpz_t r, M;
   mp_int_init(&r);
   mp_int_init(&M);
   mp_int_read_unsigned(&M,input,30);
   mp_int_exptmod(&M,e,n,&r);
   mp_int_to_unsigned(&r,output,32);
   mp_int_clear(&r);
   mp_int_clear(&M);
}

/**
\param n - public key
\param d - public key
\param input - input buffer (length 32)
\param output - output buffer (length 30)
*/
void decrypt(mp_int n, mp_int d, unsigned char *input, unsigned char *output)
{
   int len;
   mpz_t r, M;
   mp_int_init(&r);
   mp_int_init(&M);
   mp_int_read_unsigned(&M,input,32);
   mp_int_exptmod(&M,d,n,&r);

   memset(output,0,30);
   len = mp_int_unsigned_len(&r);
   mp_int_to_unsigned(&r,output+(30-len),len);

   mp_int_clear(&r);
   mp_int_clear(&M);
}

void test2(mp_int n, mp_int d, mp_int e)
{
   mpz_t M, Me, Mn;

   mp_int_init(&M);
   mp_int_init(&Me);
   mp_int_init(&Mn);

   mp_int_read_string(&M,10,«790175210722»);
   mp_int_exptmod(&M,e,n,&Me);

   mp_int_exptmod(&Me,d,n,&Mn);

   mp_print(«M»,&M);
   mp_print(«Me»,&Me);
   mp_print(«Mn»,&Mn);
}

void test()
{
   int i;
   mpz_t p, q, n, f, e, d;

   unsigned char in[30];
   unsigned char enc[32];
   unsigned char out[30];

   mp_int_init(&p);
   mp_int_init(&q);
   mp_int_init(&n);
   mp_int_init(&f);
   mp_int_init(&e);
   mp_int_init(&d);

   /* Prime number
    * In maxima
    * p:prev_prime(random(2^128));
    * q:prev_prime(random(2^128));
    */
   mp_int_read_string(&p,10,«223047569111165845044801989752398661849»);
   mp_int_read_string(&q,10,«240255032543754176698722024961108766087»);

   //n:p*q ~256bit
   mp_int_read_string(&n,10,«535883009756084089652392291053128557767»
                «76530189257166890195158914202351914863»);

   //euler
   //f:(p-1)*(q-1)
   mp_int_read_string(&f,10,«5358830097560840896523922910531285»
                «5776313227587602246868451634899488844486928»);

   //1 < e < f
   //In Maxima
   //e:prev_prime(random(f));
   mp_int_read_string(&e,10,«112470912696992876965517413114»
                «66085899391567613526265626000091663564885625161»);

   //d*e = 1 + k*f
   //In Maxima
   //d:inv_mod(e,f);
   mp_int_read_string(&d,10,«148357171061466109504623113237»
                «38173934393566182755413872859047620251494879129»);

   for ( i = 0; i < 30; ++i ) {
      in[i] = i;
   }

   encrypt(&n,&e,in,enc);
   decrypt(&n,&d,enc,out);

   for ( i = 0; i < 30; ++i ) {
      printf(«%d\n»,in[i]);
   }

   puts(«===========»);


   for ( i = 0; i < 30; ++i ) {
      printf(«%d\n»,out[i]);
   }

   mp_int_clear(&p);
   mp_int_clear(&q);
   mp_int_clear(&n);
   mp_int_clear(&f);
   mp_int_clear(&e);
   mp_int_clear(&d);
}

olegk ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.