Форум программистов, компьютерный форум, киберфорум
C++/CLI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
3 / 3 / 2
Регистрация: 18.12.2014
Сообщений: 64

Не работает функция дешифровки строки из AES

25.08.2015, 18:50. Показов 3123. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я не знаю, что я делаю не так, потому что на вашем форуме в разделе "C++/CLI Windows Forms" есть всего одна тема со словом "aes", и та без ответов.
Функция шифрования взята с сайта микромягкого и немного переделана под крестовые NET-штучки (был пример только на решетке). Выглядит она EncryptStringToBytes_Aes(жертва, ключ, вектор):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
array<Byte>^ EncryptStringToBytes_Aes(String^ plainText, array<Byte>^ Key, array<Byte>^ IV)
{
    array<Byte>^ encrypted;
    AesManaged^ aesAlg = gcnew AesManaged();
    aesAlg->Key = Key;
    aesAlg->IV = IV;
    ICryptoTransform^ encryptor = aesAlg->CreateEncryptor(aesAlg->Key, aesAlg->IV);
    MemoryStream^ msEncrypt = gcnew MemoryStream();
    CryptoStream^ csEncrypt = gcnew CryptoStream(msEncrypt, encryptor, CryptoStreamMode::Write);
    StreamWriter^ swEncrypt = gcnew StreamWriter(csEncrypt);
    swEncrypt->Write(plainText);
    swEncrypt->Close();
    csEncrypt->Close();
    msEncrypt->Close();
    encrypted = msEncrypt->ToArray();
 
//ниже моя фича, предполагающая возможность расшифровки исходной строки:
//массив result в первых 16 байтах содержит тот самый инициализирующий вектор,
//все остальное в массиве - зашифрованная строка
    array<Byte>^ result = gcnew array<Byte>(IV->Length + encrypted->Length);
    for(int i=0; i<IV->Length; i++)        result[i] = IV[i];
    for(int i=0; i<encrypted->Length; i++) result[i + IV->Length] = encrypted[i];
 
    return result;
}
Если это кого-то интересует, то ключ получается так:
C++
1
2
3
4
5
6
7
8
9
10
11
array<Byte>^ getKey(String^ keyS/*нечто, определяемое пользователем*/)
{
    MD5^ md5 = gcnew MD5CryptoServiceProvider;
    array<Byte>^ mySalt = md5->ComputeHash(Encoding::UTF8->GetBytes("0123456789"));
//тут мы просто сто раз вычисляем хэш от "0123456789" в качестве криптосоли
    for(int i=0; i<99; i++) mySalt = md5->ComputeHash(mySalt);
 
    Rfc2898DeriveBytes^ k1 = gcnew Rfc2898DeriveBytes(keyS, mySalt);
//на выходе 32 бессмысленных байта
    return k1->GetBytes(32);
}
Вектор создается рандомно.
Все вышеуказанные ф-и нормально работают. Теперь проблема: функция дешифровки взята из той же справки микромягкого, что и шифрования.
Выглядит DecryptStringFromBytes_Aes(зашифрованная жертва, ключ, вектор):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String^ DecryptStringFromBytes_Aes(array<Byte>^ cipherText, array<Byte>^ Key, array<Byte>^ IV)
{
    AesManaged^ aesAlg = gcnew AesManaged();
    aesAlg->Key = Key;
    aesAlg->IV = IV;
    ICryptoTransform^ decryptor = aesAlg->CreateDecryptor(aesAlg->Key, aesAlg->IV);
 
    String^ plaintext=nullptr;
    MemoryStream^ msDecrypt = gcnew MemoryStream(cipherText);
    CryptoStream^ csDecrypt = gcnew CryptoStream(msDecrypt, decryptor, CryptoStreamMode::Read);
    StreamReader^ srDecrypt = gcnew StreamReader(csDecrypt);
    plaintext = srDecrypt->ReadToEnd();
    srDecrypt->Close();
    csDecrypt->Close();
    msDecrypt->Close();
    return plaintext;
}
Ошибка на строке 12: "System.Security.Cryptography.Cryptograp hicException: Недопустимая длина данных для дешифрования".
Подробное описание:
System.Security.Cryptography.Cryptograph icException: Недопустимая длина данных для дешифрования.
в System.Security.Cryptography.RijndaelMan agedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
в System.Security.Cryptography.CryptoStrea m.Read(Byte[] buffer, Int32 offset, Int32 count)
в System.IO.StreamReader.ReadBuffer()
в System.IO.StreamReader.ReadToEnd()
в тестaes.Form1.DecryptStringFromBytes_Aes (Byte[] cipherText, Byte[] Key, Byte[] IV) в некий_путь\form1.h:строка такая-то
Вот код формочки и пример работы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#pragma once
 
namespace тестaes {
 
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
 
    using namespace System::IO;
    using namespace System::Security::Cryptography;
    using namespace System::Text;
 
    /// <summary>
    /// Сводка для Form1
    /// </summary>
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            //
            //TODO: добавьте код конструктора
            //
        }
 
    protected:
        /// <summary>
        /// Освободить все используемые ресурсы.
        /// </summary>
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }
    private: System::Windows::Forms::TextBox^ textBox1;
    private: System::Windows::Forms::TextBox^ textBox2;
    private: System::Windows::Forms::TextBox^ textBox3;
    private: System::Windows::Forms::Button^ button1;
    private: System::Windows::Forms::TextBox^ textBox4;
    private: System::Windows::Forms::Label^ label1;
    private: System::Windows::Forms::Label^ label2;
        /// <summary>
        /// Требуется переменная конструктора.
        /// </summary>
        System::ComponentModel::Container ^components;
 
#pragma region Windows Form Designer generated code
        /// <summary>
        /// Обязательный метод для поддержки конструктора - не изменяйте
        /// содержимое данного метода при помощи редактора кода.
        /// </summary>
        void InitializeComponent(void)
        {
            this->textBox1 = (gcnew System::Windows::Forms::TextBox());
            this->textBox2 = (gcnew System::Windows::Forms::TextBox());
            this->textBox3 = (gcnew System::Windows::Forms::TextBox());
            this->button1 = (gcnew System::Windows::Forms::Button());
            this->textBox4 = (gcnew System::Windows::Forms::TextBox());
            this->label1 = (gcnew System::Windows::Forms::Label());
            this->label2 = (gcnew System::Windows::Forms::Label());
            this->SuspendLayout();
            // 
            // textBox1
            // 
            this->textBox1->Font = (gcnew System::Drawing::Font(L"Lucida Console", 9, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
            static_cast<System::Byte>(204)));
            this->textBox1->Location = System::Drawing::Point(56, 12);
            this->textBox1->Multiline = true;
            this->textBox1->Name = L"textBox1";
            this->textBox1->Size = System::Drawing::Size(337, 30);
            this->textBox1->TabIndex = 0;
            // 
            // textBox2
            // 
            this->textBox2->Font = (gcnew System::Drawing::Font(L"Lucida Console", 9, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
            static_cast<System::Byte>(204)));
            this->textBox2->Location = System::Drawing::Point(56, 62);
            this->textBox2->Name = L"textBox2";
            this->textBox2->Size = System::Drawing::Size(337, 19);
            this->textBox2->TabIndex = 1;
            // 
            // textBox3
            // 
            this->textBox3->Font = (gcnew System::Drawing::Font(L"Lucida Console", 9, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
            static_cast<System::Byte>(204)));
            this->textBox3->Location = System::Drawing::Point(15, 87);
            this->textBox3->Multiline = true;
            this->textBox3->Name = L"textBox3";
            this->textBox3->Size = System::Drawing::Size(206, 88);
            this->textBox3->TabIndex = 2;
            // 
            // button1
            // 
            this->button1->Location = System::Drawing::Point(83, 196);
            this->button1->Name = L"button1";
            this->button1->Size = System::Drawing::Size(75, 23);
            this->button1->TabIndex = 3;
            this->button1->Text = L"button1";
            this->button1->UseVisualStyleBackColor = true;
            this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
            // 
            // textBox4
            // 
            this->textBox4->Font = (gcnew System::Drawing::Font(L"Lucida Console", 9, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
            static_cast<System::Byte>(204)));
            this->textBox4->Location = System::Drawing::Point(227, 87);
            this->textBox4->Multiline = true;
            this->textBox4->Name = L"textBox4";
            this->textBox4->Size = System::Drawing::Size(206, 88);
            this->textBox4->TabIndex = 2;
            // 
            // label1
            // 
            this->label1->AutoSize = true;
            this->label1->Location = System::Drawing::Point(14, 12);
            this->label1->Name = L"label1";
            this->label1->Size = System::Drawing::Size(36, 13);
            this->label1->TabIndex = 4;
            this->label1->Text = L"Ключ:";
            // 
            // label2
            // 
            this->label2->AutoSize = true;
            this->label2->Location = System::Drawing::Point(4, 62);
            this->label2->Name = L"label2";
            this->label2->Size = System::Drawing::Size(46, 13);
            this->label2->TabIndex = 4;
            this->label2->Text = L"Вектор:";
            // 
            // Form1
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(449, 262);
            this->Controls->Add(this->label2);
            this->Controls->Add(this->label1);
            this->Controls->Add(this->button1);
            this->Controls->Add(this->textBox4);
            this->Controls->Add(this->textBox3);
            this->Controls->Add(this->textBox2);
            this->Controls->Add(this->textBox1);
            this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
            this->MaximizeBox = false;
            this->Name = L"Form1";
            this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
            this->Text = L"Form1";
            this->ResumeLayout(false);
            this->PerformLayout();
 
        }
#pragma endregion
 
        array<Byte>^ EncryptStringToBytes_Aes(String^ plainText, array<Byte>^ Key, array<Byte>^ IV)
        {
            array<Byte>^ encrypted;
            AesManaged^ aesAlg = gcnew AesManaged();
            aesAlg->Key = Key;
            aesAlg->IV = IV;
            ICryptoTransform^ encryptor = aesAlg->CreateEncryptor(aesAlg->Key, aesAlg->IV);
            MemoryStream^ msEncrypt = gcnew MemoryStream();
            CryptoStream^ csEncrypt = gcnew CryptoStream(msEncrypt, encryptor, CryptoStreamMode::Write);
            StreamWriter^ swEncrypt = gcnew StreamWriter(csEncrypt);
            swEncrypt->Write(plainText);
            swEncrypt->Close();
            csEncrypt->Close();
            msEncrypt->Close();
            encrypted = msEncrypt->ToArray();
 
            array<Byte>^ result = gcnew array<Byte>(IV->Length + encrypted->Length);
            for(int i=0; i<IV->Length; i++) result[i] = IV[i];
            for(int i=0; i<encrypted->Length; i++) result[i+IV->Length] = encrypted[i];
 
            return result;
        }
 
        String^ DecryptStringFromBytes_Aes(array<Byte>^ cipherText, array<Byte>^ Key, array<Byte>^ IV)
        {
            AesManaged^ aesAlg = gcnew AesManaged();
            aesAlg->Key = Key;
            aesAlg->IV = IV;
            ICryptoTransform^ decryptor = aesAlg->CreateDecryptor(aesAlg->Key, aesAlg->IV);
 
            String^ plaintext=nullptr;
            MemoryStream^ msDecrypt = gcnew MemoryStream(cipherText);
            CryptoStream^ csDecrypt = gcnew CryptoStream(msDecrypt, decryptor, CryptoStreamMode::Read);
            StreamReader^ srDecrypt = gcnew StreamReader(csDecrypt, Encoding::UTF8, false, 256);
            try{
                plaintext = srDecrypt->ReadToEnd();
                srDecrypt->Close();
                csDecrypt->Close();
                msDecrypt->Close();
            }catch(Exception^ ex){ 
                textBox4->Text = ex->ToString();}
            return plaintext;
        }
 
        array<Byte>^ getKey(String^ keyS)
        {
            MD5^ md5 = gcnew MD5CryptoServiceProvider;
            array<Byte>^ mySalt = md5->ComputeHash(Encoding::UTF8->GetBytes("0123456789"));
            for(int i=0; i<99; i++) mySalt = md5->ComputeHash(mySalt);
 
            Rfc2898DeriveBytes^ k1 = gcnew Rfc2898DeriveBytes(keyS, mySalt);
            return k1->GetBytes(32);
        }
 
    private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) 
        {
            String^ original = "Encrypt me!";
            AesManaged^ aesAlg = gcnew AesManaged();
            aesAlg->Key = getKey("test");
            array<Byte>^ i = aesAlg->IV;
            array<Byte>^ encrypted = EncryptStringToBytes_Aes(original, aesAlg->Key, i);
            String^ decrypted = DecryptStringFromBytes_Aes(Encoding::UTF8->GetBytes(original), aesAlg->Key, i);
 
            textBox1->Text = BitConverter::ToString(aesAlg->Key)->Replace("-", " ");
            textBox2->Text = BitConverter::ToString(i)->Replace("-", " ");
            textBox3->Text = BitConverter::ToString(encrypted)->Replace("-", " ");
            //textBox4->Text = decrypted;
        }
 
    };
}
(проект называется "тест aes", просто тыкайте кнопку)
Что я делаю не так?
Миниатюры
Не работает функция дешифровки строки из AES  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.08.2015, 18:50
Ответы с готовыми решениями:

Ошибка дешифровки AES в Android: pad block corrupted
Приветствую. В обучающих целях написал на Java программу для хранения паролей, использующую шифрование AES. Написал класс, в котором...

Нужна простая функция шифровки и фича дешифровки XOR
У кого есть дайте, но чтобы было очень просто сразу вставить не думая. Неохота как-то вникать в это... (НЕ ТРОЛИТЬ) Добавлено через 12...

Не работает функция проверки и разбиения строки
Привет! Имеется макрос, заполняющий шаблон Word документа значениями из ячеек Excel. В данном макросе есть функция проверки значения в...

21
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18428 / 14358 / 5372
Регистрация: 17.03.2014
Сообщений: 29,039
Записей в блоге: 1
01.09.2015, 23:46
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Иван_Богданов Посмотреть сообщение
Как в * может читаться неправильное кол-во байт
Не знаю как. Приведенная тобой реализация работает без ошибок. Возможно была какая-то ошибка которую ты исправил.

Цитата Сообщение от Иван_Богданов Посмотреть сообщение
"...удаление экземпляра AesManaged" - этим должен заниматься сборщик мусора
Сборщик мусора управляет только памятью. Кроме памяти есть и другие вещи которые надо освобождать после использования. "Удаление" экземпляра AesManaged нужно чтобы вызвался метод Dispose(). Если этого не сделать, то время жизни может оказаться длинее чем нужно. Что в свою очередь может привести к багам. Поэтому следует приучать себя к вызову delete для типов реализующих интерфейс IDisposable. Класс AesManaged является именно таким типом.

Цитата Сообщение от Иван_Богданов Посмотреть сообщение
при шифровании файла никаких исключений пока не выплевывалось, так что ловить там их мне не нужно
Если их нет сейчас, то это не означает что их не будет в будущем. В данном случае обработка исключений нужна только для корректного освобождения ресурсов. Поэтому в моем примере и используется try/finally блок.
0
3 / 3 / 2
Регистрация: 18.12.2014
Сообщений: 64
02.09.2015, 16:18  [ТС]
интересно
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.09.2015, 16:18

Шифрование строки AES (готовое решение)
искал на форуме простое шифрование строки с AES но не смог найти что искал может плохо искал в конце разобрался решил скинуть может...

Получение ключа для AES шифрования из строки
Здравствуйте, есть строка в формате string, имеющая 32 символа (хеш md5). Нужно эту строку преобразовать в byte 128bit, для использования в...

AES 192 и AES 256
Добрый день! Возможно ли в Java сделать шифрование с помощью AES 256- или 192-битными ключами? Единственное условие, что мешает мне...

Функция Copies(s,s1,n) Назначение: копирование строки s в строку s1 n раз. Прога ниже из форума, но она не работает
#include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;string&gt; using namespace std; std::string string_multiplier(const...

Функция корректно работает в Delphi 7 и не неверно работает в RAD Studio 10
Переписываю свою программу с Delphi 7 под RAD Studio 10. Столкнулся с проблемой - функция в Delphi 7 возвращает правильное значение, в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
22
Ответ Создать тему
Новые блоги и статьи
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru