Тема: Криптографія, шифрування великих файлів

Зацікавило мене таке питання: Як шифрувати великі файли ? (скажімо 100гб один файл)
RSA алгоритм якби мені зрозумілий.

Є приватний ключ і відкритий (їх потрібно створити), про приватний писати поки що не буду, почну з публічного, публічний {e - 5, n - 21} де е - степінь, n - модуль.

Я хочу зашифрувати 19, 19 ^ 5 mod 21 = 10

А тепер що до великого файлу (100 гб)

Як зчитати такий великий файл ? ( оперативної пам'яті точно не вистачить. )

Можна, звичайно, розбити файл на менші частинки, але як тоді визначити найбільш оптимальний розмір для розбиття ? Чи від розміру нічого не залежить ? (наприклад 854126715 ^ 5 mod 21 те саме по часі (не по результату) що 854 ^ 5 mod 21, 126 ^ 5 mod 21, 715 ^ 5 mod 21)

Як можна порахувати час шифрування, якщо я буду використовувати для арифметики бібліотеки GMP ?

Підкажіть як зашифрувати великий файл за допомогою RSA ? ( Тільки не пропонуйте інших алгоритмів шифрування, мене цікавить саме цей. )

2

Re: Криптографія, шифрування великих файлів

За допомогою асиметричного шифрування не можна зашифрувати дані, більші ніж ключ. Ніхто не використовує його для шифрування великих файлів. Зазвичай RSA використовують для передачі симетричного ключа, який шифрує власне файл.

Якщо вже дуже хочеться, так чи інакше треба буде розбивати файл на менші частини і шифрувати частинки. Зчитали частину файлу до буфера, зашифрували, дописали до вихідного файлу. Дешифровка в зворотньому напрямку. Розмір буфера при тому, звичайно, має бути однаковий і не більше розміру ключа.

Подякували: 0xDADA11C7, Torbins, quez, Betterthanyou4

3 Востаннє редагувалося Torbins (12.01.2017 12:33:00)

Re: Криптографія, шифрування великих файлів

Підтримую iovchynnikov.
Для сучасних компів, мені здається, буфер близько одного мегабайта буде оптимальним. З меншим буфером будуть тормоза через надто часті звертання до диску, а з більшим - зайва витрата оперативки. Хоча по-хорошому тут треба робити тести.

Подякували: Betterthanyou, iovchynnikov2

4 Востаннє редагувалося Betterthanyou (12.01.2017 16:41:29)

Re: Криптографія, шифрування великих файлів

В мене ще одне питання, про кодування інформації (перетворення з одного виду і інший) (не шифрування)
Якщо я буду зчитувати побайтно файл, а потім перетворювати в число

((int)зчитати_символ()) + '0';

//пояснення
//зчитати_символ() - функція що зчитає один символ з файлу
//(int) - явне перетворення в число
// + '0' - перетворення назад в рядок символів

то це буде довго, і число вийде більше чим потрібно.

наприклад unsigned int може приймати 0 to 4'294'967'295 (я знаю ще не завжди, але є ж бібліотека climits по якій можна орієнтуватися) значень, тобто максимум цифр 10, а якщо робити так як я зверху написав вийде максимум 255'255'255'255, тобто 12 цифр

Ще раз коротко що я хочу
є файл (наприклад текстовий) там записано "g8h8", але це не має значення
в бітах це виглядає так 01100111 00111000 01101000 00111000 (а це вже має значення)
якщо кодувати це число так як я вище писав то вийде 103 056 104 056
а якщо його кодувати як число то буде 1 731 749 943, тобто 2 цифри економиться
з більшим об'ємом інформації ця економія буде збільшуватися

Я хочу щоб біти кодувалися як число, але записувалися в символьний рядок типу char, як це зробити ?
(в файл 01100111 00111000 01101000 00111000 bit - я хочу зчитати як символьний рядок "1731749943" )

Можливо у вас виникне питання: як же я дізнався що 01100111 00111000 01101000 00111000 - це  1 731 749 943 якщо я не знаю як кодувати

Я написав такий код, зрозуміло що він жахливо повільно працює

    
unsigned int num(4'294'967'295);/*в стандарті C++ 14 можна розділяти число апострофом(для зручності), але форум ще це не підтримує*/
    char ch[]("g8h8");

    string s1(""),
        s2("");

    do
    {
        s1.clear();
        s2.clear();

        s2 = bitset<32>(num--).to_string<char, std::string::traits_type, std::string::allocator_type>();
    
        for (int i(0); i < 4; i++)
            s1 += bitset<8>(ch[i]).to_string<char, std::string::traits_type, std::string::allocator_type>();

        if (num == 1)
        {
            cout << "Error!!!";
            getchar();
        }
        
    } while (s1 != s2);

    cout << "ch  = " << s1 << "\nnum = " << s2 << '\n' <<
        "num = " << num;

5

Re: Криптографія, шифрування великих файлів

а те, що в бітах виглядає як 00000000 00000000 00000000 00000000, можна записати як 0. Виникає питання, як розділяти "0" і "1731749943", і наступні числа.

Подякували: Betterthanyou1

6 Востаннє редагувалося Betterthanyou (12.01.2017 20:17:09)

Re: Криптографія, шифрування великих файлів

Yola написав:

а те, що в бітах виглядає як 00000000 00000000 00000000 00000000, можна записати як 0. Виникає питання, як розділяти "0" і "1731749943", і наступні числа.

ну так це ж логічного
наприклад
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111
те саме з іншими числами

7

Re: Криптографія, шифрування великих файлів

http://truecrypt.sourceforge.net/

Подякували: Betterthanyou1

8

Re: Криптографія, шифрування великих файлів

Betterthanyou написав:

ну так це ж логічного
наприклад
0 000
1 001
2 010
...
те саме з іншими числами

Я мав на увазі саме розділяти, а не розрізняти. Ви ж отримали ці числа і хочте їх знов кудись записати, а потім знов читати? тож, як ви розумітимете, що одне число вже закінчилось і почалось інше.

Було б добре говорити в двійковій системі, бо записуємо/читаємо ми біти. Але для розуміння концепції можна й у десятковій.

9 Востаннє редагувалося Betterthanyou (12.01.2017 21:33:36)

Re: Криптографія, шифрування великих файлів

Ні, ви не так мене зрозуміли
Я хочу зчитати число 01100111 00111000 01101000 00111000
далі я хочу отримати десяткове число 1731749943
це десяткове число я шифрую за допомогою RSA
і отримую нове десяткове число
нове число (десяткове) назад перетворюю в бити і тоді записую

ну от приклад як записати int у файл як число (а не як текст)

int y=0; //Y це записуємо у файл
 int x=0; //X це зчитуємо з файлу
 
cout<<"Y = ";
cin>>y;
ofstream out("C://1.txt",ios::binary|ios::out); 
   out.write((char*)&y,sizeof y); 
 out.close(); 
 
 
 ifstream in("C://1.txt",ios::binary|ios::in);
   in.read((char*)&x,sizeof x); 
 in.close();
 
 cout<<"x = "<<x<<endl;

воно ж розпізнає його

введіть 1731749943 а потім відкрийте файл

Ви вводили число а отримали символи 7h8g

Я хочу те саме тільки в більших об'ємах, хоча б 1 мб

тобто я зчитав 1 мб інформації, і цю інформацію я хочу бачити як число
оскільки немає жодного типу що вміщує 1 мб (обмежує машинне слово) то ці цифри мають бути в рядку

файл
01100111 00111000 01101000 00111000 .... 01100111 00111000 01101000 00111000

я його зчитую

і отримую рядок типу char "896874...5451242"

тепер зрозуміло чи ще ні ? (якщо і то пишіть що, я розумію що дуже заплутано пояснюю)

10

Re: Криптографія, шифрування великих файлів

Якщо я правильно розумію проблему (що наврят, бо схоже що ви її не розумієте) то гляньте оце https://en.wikipedia.org/wiki/LEB128

Подякували: Betterthanyou, iovchynnikov, 0xDADA11C73

11

Re: Криптографія, шифрування великих файлів

0x9111A написав:

Якщо я правильно розумію проблему (що наврят, бо схоже що ви її не розумієте) то гляньте оце https://en.wikipedia.org/wiki/LEB128

так це те що я хотів, дуже дякую

12

Re: Криптографія, шифрування великих файлів

А чому не можна створити масив int на 256*1024 елементів? int має розмір 4 байта, отже масив буде рівно 1 Мб. Цей масив читати з файлу увесь за один раз. І далі з ним працювати. Єдина проблема, що в кінці файлу залишиться менше мегабайта даних, і масив буде заповнений не повністю.

Подякували: Betterthanyou1