1
我試圖通過tcp連接從C#程序向C++程序發送加密字符串。當它試圖解密字符串時,C++程序在crypto ++中崩潰。我可以在調試器中看到該字符串大部分已解碼,但未正確終止。例如,如果我送的 「Hello world」,它就會被解密爲 「世界,你好%% @#$ @#」(末尾垃圾)將C#AES加密字符串發送到CyptoPP C++程序進行解密
下面是如何加密
//Create byte arrays to hold original, encrypted, and decrypted data.
byte[] dataToEncrypt = ByteConverter.GetBytes(data);
byte[] key = new byte[16];
for (int i = 0; i < 16; ++i)
{
key[i] = 1;
}
byte[] iv = new byte[16];
for (int i = 0; i < 16; ++i)
{
iv[i] = 1;
}
RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.Key = key;
myRijndael.IV = iv;
byte[] encrypted = encryptStringToBytes_AES(data, myRijndael.Key, myRijndael.IV);
// sends the byte array via active tcp connection
_transport.SendEncryptedData(encrypted);
static byte[] encryptStringToBytes_AES(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the stream used to encrypt to an in memory
// array of bytes.
MemoryStream msEncrypt = null;
// Declare the RijndaelManaged object
// used to encrypt the data.
RijndaelManaged aesAlg = null;
try
{
// Create a RijndaelManaged object
// with the specified key and IV.
aesAlg = new RijndaelManaged();
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create an encrypto to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
msEncrypt = new MemoryStream();
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
}
}
finally
{
// Clear the RijndaelManaged object.
if (aesAlg != null)
aesAlg.Clear();
}
// Return the encrypted bytes from the memory stream.
return msEncrypt.ToArray();
}
這裏是C++側解密與加密++
byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ];
byte iv[ CryptoPP::AES::BLOCKSIZE ];
::memset(key, 0x01, CryptoPP::AES::DEFAULT_KEYLENGTH);
::memset(iv, 0x01, CryptoPP::AES::BLOCKSIZE);
std::string decryptedtext;
CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv);
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedtext));
// CRASHES IN .PUT(...)
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(data), len + 1);
stfDecryptor.MessageEnd();
RijndaelManaged的默認值是PaddingMode.PKCS7。 CryptoPP的默認值是DEFAULT_PADDING ...找不到更多。沿着這個答案的線,我會建議改變StreamTransformationFilter有可選的填充第三個參數,並把PKCS選項。 –
「DEFAULT_PADDING表示如果c.MandatoryBlockSize()> 1 && c.MinLastBlockSize()== 0(例如ECB或CBC模式),否則NO_PADDING(OFB,CFB,CTR,CBC-CTS模式),則表示PKCS_PADDING。 [鏈接](http://www.cryptopp.com/docs/ref/class_stream_transformation_filter.html)所以它應該使用PKCS。我敢打賭,這是空終結者,我越想越想。 – Luke