Я пытаюсь сопоставить схемы шифрования на c ++ с использованием crypto ++ и c # и не могу получить одинаковые результаты на обоих. Они оба работают над собой, но не от одного к другому. Любая помощь будет отличной!
C ++ код с использованием Crypto ++:
std::string key = "01286567891233460123456789123456";
std::string iv = "0123456789123456";
std::string encrypt(const std::string& str_in)
{
std::string str_out;
CryptoPP::AES::Encryption aesEncryption((byte*)key.c_str(), CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, (byte*)iv.c_str());
StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(str_out));
stfEncryptor.Put(reinterpret_cast<const unsigned char*>(str_in.c_str()), str_in.length() + 1);
stfEncryptor.MessageEnd();
return str_out;
}
std::string decrypt(const std::string& cipher_text)
{
std::string str_out;
CryptoPP::AES::Decryption aesDecryption((byte*)key.c_str(), CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, (byte*)iv.c_str());
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(str_out));
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(cipher_text.c_str()), cipher_text.size());
stfDecryptor.MessageEnd();
return str_out;
}
Код Ран:
std::string str = encrypt("123456789012345");
str = decrypt(str);
Этот вывод:
Encrypted: Ö&qcƒ“¹yLY»Lïv¹w“¼LLŠÀ¶ó¢,óð9·
Length: 32
Decrypted: 123456789012345
Length: 16
Теперь в C # у меня есть следующий код:
public string Encrypt(string clearText)
{
byte[] clearBytes = Encoding.Default.GetBytes(clearText);
using (Aes encryptor = Aes.Create("AES"))
{
// encryptor.BlockSize = 128;
encryptor.Padding = PaddingMode.Zeros;
encryptor.KeySize = 128;
encryptor.Mode = CipherMode.CBC;
encryptor.Key = Encoding.Default.GetBytes("01234567891234560123456789123456");
encryptor.IV = Encoding.Default.GetBytes("0123456789123456");
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
byte[] bt = ms.ToArray();
clearText = Encoding.Default.GetString(bt);// Convert.ToBase64String(bt);
}
}
return clearText; //Return the encrypted command
}
public string Decrypt(string cipherText)
{
byte[] clearBytes = Encoding.Default.GetBytes(cipherText);
using (Aes decryptor = Aes.Create("AES"))
{
// decryptor.BlockSize = 128;
decryptor.Padding = PaddingMode.Zeros;
decryptor.KeySize = 128;
decryptor.Mode = CipherMode.CBC;
decryptor.Key = Encoding.Default.GetBytes("01286567891233460123456789123456");
decryptor.IV = Encoding.Default.GetBytes("0123456789123456");
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, decryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
byte[] bt = ms.ToArray();
cipherText = Encoding.Default.GetString(bt);// Convert.ToBase64String(bt);
}
}
return cipherText; //Return the decrypted text
}
}
Код работал:
string orig = "123456789012345";
string cipher = Encrypt(orig);
string dedata = Decrypt(cipher);
Результаты:
Orig: 123456789012345
Encrypted: êßyoº0¦ëì›X˜Ü
Length: 16
Decrypted: 123456789012345
Length: 16
Как видите, зашифрованные строки оказываются разными. Поэтому, когда я беру зашифрованную строку в c ++, она не может расшифровать ее в c #, как показано здесь:
bytes[] encryptedText = ENCRYPTED TEXT FROM C++
text = System.Text.Encoding.Default.GetString(encryptedText);
text = Decrypt(text);
C ++ возвращает 32 байта для своей зашифрованной строки, которую я считаю добавляемым дополнением. Не уверен, как повторить это в коде c # или наоборот, чтобы все соответствовало. Не уверен, что здесь что-то еще мне не хватает ... Спасибо за любую помощь!
EDIT:
Я сопоставил ключи, и теперь строка совпадает на обоих концах, за исключением разницы заполнения. Когда я пытаюсь расшифровать строку в C #, он говорит мне, что входные данные имеют неправильный размер блока? Любая помощь с этим сейчас?
ИЗМЕНИТЬ СНОВА:
Кажется, что она генерирует одну и ту же байтовую строку для каждой функции шифрования c # и c ++, поэтому проблема решена. Мне кажется, что проблема на стороне c # - я получаю зашифрованную строку и преобразую байты с помощью: text = System.Text.Encoding.Default.GetString (recvBuf); recvBuf - это зашифрованная строка из c ++, в которой отсутствует последний символ строки. Это совпадает со строкой c ++ минус последний символ ?? Не уверен, почему это происходит.
Например, мой c ++ отправляет по этой зашифрованной строке: Ö & qcƒ «LYyLY» Liv, а моя программа на c # получит только следующее: Ö & qcƒ «¹yLY» Lï, что, в свою очередь, приведет к сбою при расшифровке. Зашифрованная строка отправляется через сокет TCP, если это имеет какое-либо значение.
EDIT
Все еще отсутствуют байты после изменения кодирования и декодирования на base64 на обоих концах.
C++ 1iZxY4OTHrl5TFm7Gkzvdrl3k7xMTIrAtvOiLPPwObc=
C# 1iZxY4OTHrl5TFm7Gkzvdg==
C# RECEIVED 1iZxY4OTHrl5TFm
Новый код C #:
public string Encrypt(string clearText)
{
byte[] clearBytes = Encoding.Default.GetBytes(clearText);
using (Aes encryptor = Aes.Create("AES"))
{
// encryptor.BlockSize = 128;
encryptor.Padding = PaddingMode.Zeros;
encryptor.KeySize = 128;
encryptor.Mode = CipherMode.CBC;
encryptor.Key = Encoding.Default.GetBytes("01286567891233460123456789123456");
encryptor.IV = Encoding.Default.GetBytes("0123456789123456");
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
byte[] bt = ms.ToArray();
clearText = Convert.ToBase64String(bt);
}
}
return clearText; //Return the encrypted command
}
и код C ++:
std::string encrypt(const std::string& str_in)
{
std::string str_out;
std::string str_out2;
CryptoPP::AES::Encryption aesEncryption((byte*)key.c_str(), CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, (byte*)iv.c_str());
StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(str_out));
stfEncryptor.Put(reinterpret_cast<const unsigned char*>(str_in.c_str()), str_in.length() + 1);
stfEncryptor.MessageEnd();
str_out2 = base64_encode(reinterpret_cast<const unsigned char*>(str_out.c_str()), strlen(str_out.c_str()));
return str_out2;
}
РЕДАКТИРОВАТЬ
ЭТО РАБОТАЕТ !!! Это было просто упущением с моей стороны, мой сокет проверял размер данных перед шифрованием и отправлял этот размер вместо размера зашифрованной строки. Исправить это и все это работает идеально. Спасибо Брэндон за помощь!