我在Rabbit微處理器上使用Dynamic C編程語言。我相信Dynamic C是基於ANSI-C89的,有一些非常微小的變化。他們有一個AES加密庫,我試圖用它來加密數據,然後再將它發送到我的服務器(很少成功)。AES加密/解密 - 動態C到C#
下面是我使用的基於C-AES功能的文檔:
AESinitStream
語法:void AESinitStream(AESstreamState *狀態, 爲const char *鍵, 常量char * init_vector);
描述:設置流狀態結構以開始加密或解密流。一個特定的流狀態只能用於一個方向的 。
PARAMETER1:狀態 - 一個AESstreamState結構被初始化
PARAMETER2:鍵 - 16字節的加密密鑰,使用NULL指針將防止 被重新計算現有的密鑰。
PARAMETER3:init_vector - 一個16字節的數組,表示反饋寄存器的初始狀態 。數據流的兩端必須以相同的初始化向量和密鑰開頭,即 。
AESencryptStream
語法:void AESencryptStream(AESstreamState *狀態, 字符*數據, 詮釋計數);
說明:加密字節
的陣列PARAMETER1:狀態 - AESstreamState結構
PARAMETER2:數據 - 將代替被加密的字節的陣列。
參數3:計數 - 數據數組的大小
這是我的C代碼:
const char key[] = {'\x41', '\x41', '\x37', '\x44',
'\x44', '\x34', '\x30', '\x33',
'\x30', '\x35', '\x39', '\x4e',
'\x36', '\x37', '\x30', '\x38'};
AESstreamState encrypt_state; //built in Dynamic C type
char init_vector[16];
int i;
int bufLength;
sprintf(Buf, "%s", "testabc");
bufLength = strlen(Buf);
for (i = 0; i < 16; i++)
init_vector[i] = rand() % 255;
printf("Key: ");
for (i = 0; i < sizeof(key); i++)
printf("%d ", key[i]);
printf("\n");
AESinitStream(&encrypt_state, key, init_vector); //built in Dynamic C function
AESencryptStream(&encrypt_state, Buf, bufLength); //built in Dynamic C function
printf("Data: ");
for (i = 0; i < strlen(Buf); i++)
printf("%d ", Buf[i]);
printf("\n");
//set first byte to something that lets the server know it's encrypted
//set 2nd through 16th byte to the IV (initialization vector) so every message will be different even if they have the same contents
for (i = bufLength-1; i >= 0; i--)
Buf[i+17] = Buf[i];
Buf[0] = 237; //φ
printf("IV: ");
for (i = 1; i < 17; i++)
{
printf("%d ", init_vector[i-1]);
Buf[i] = init_vector[i-1];
}
printf("\n");
輸出:
鍵:65 65 55 68 68 52 48 51 48 53 57 78 54 55 48 56
Data:249 78 60 83 130 167 37
IV:74 121 108 165 83 120 36 27 161 192 84 76 105 239 34 214
這是我的C#代碼:
private string DecryptAES(byte[] cipherText, byte[] IV)
{
byte[] key = {
0x41, 0x41, 0x37, 0x44,
0x44, 0x34, 0x30, 0x33,
0x30, 0x35, 0x39, 0x4e,
0x36, 0x37, 0x30, 0x38
};
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
{
throw new ArgumentNullException("cipherText");
}
else if (IV == null || IV.Length <= 0 || IV.Length != 16)
{
throw new ArgumentNullException("IV");
}
Console.Write("Key: ");
for (int i = 0; i < key.Length; i++)
Console.Write("{0} ", key[i]);
Console.WriteLine();
Console.Write("Data: ");
for (int i = 0; i < cipherText.Length; i++)
Console.Write("{0} ", cipherText[i]);
Console.WriteLine();
Console.Write("IV: ");
for (int i = 0; i < IV.Length; i++)
Console.Write("{0} ", IV[i]);
Console.WriteLine();
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Mode = CipherMode.CFB;
rijAlg.FeedbackSize = 8;
rijAlg.BlockSize = 128;
rijAlg.Padding = PaddingMode.None;
rijAlg.Key = key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for decryption.
using (System.IO.MemoryStream msDecrypt = new System.IO.MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (System.IO.StreamReader srDecrypt = new System.IO.StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
string plaintext = null;
plaintext = srDecrypt.ReadToEnd();
Console.WriteLine("Decrypted: " + plaintext);
return plaintext;
}
}
}
}
}
輸出:
鍵:65 65 55 68 68 52 48 51 48 53 57 78 54 55 48 56
Data:249 78 60 83 130 167 37
IV:74 121 108 165 83 120 36 27 161 192 84 76 105 239 34 214
解密:噸{^^ D2
正如你可以看到,我發現了一些奇怪的?輸出在我的解密文本中。任何人都可以指引我走向正確的方向嗎?
我曾嘗試使用動態C成功解密,但如果您認爲內置動態C AES庫是罪魁禍首,您會推薦什麼?
編輯: 所以我決定在這個用C#的AES庫加密,並得到了不同的密碼:
private byte[] EncryptStringToBytes(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");
}
byte[] encrypted = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Mode = CipherMode.CFB;
rijAlg.FeedbackSize = 8;
rijAlg.BlockSize = 128;
rijAlg.Padding = PaddingMode.None;
rijAlg.Key = Key;
rijAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (System.IO.MemoryStream msEncrypt = new System.IO.MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (System.IO.StreamWriter swEncrypt = new System.IO.StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
調用帶有相同的字符串,鍵上面的函數,& IV我最初使用結果在下面的密碼:
249(這是正確的),43,74,118,241,179,235
我將FeedbackSize更改爲16,前兩個字節正確,但它也給我一個錯誤(要加密的數據的長度無效),並將數組大小減小到6個字節。我無能爲力。
這裏是一些使用AESencryptStream的兔子示例代碼片段(他們選擇將IV設置爲與鍵值相同的值)。看來,我正確地使用這個功能,但請告訴我,如果我錯了:
const char key[16] = {
'\x06', '\xa9', '\x21', '\x40', '\x36', '\xb8', '\xa1', '\x5b',
'\x51', '\x2e', '\x03', '\xd5', '\x34', '\x12', '\x00', '\x06'
};
char bblock[8192];
AESstreamState ass;
memset(bblock, 'A', sizeof(bblock));
AESinitStream(&ass, key, key);
AESencryptStream(&ass, bblock, sizeof(bblock));
AESinitStream(&ass, key, key);
AESdecryptStream(&ass, bblock, sizeof(bblock));
哪個鏈接模式你的C AES庫使用?另外你的密文長度沒有意義,因爲它應該是塊長度的多倍(16字節) –
更新:它看起來像你濫用加密函數以及..不能告訴更多,因爲我沒有文檔。但它對我來說沒有多大意義,你對可憐的Buf做了什麼...... –
我正在使用CFB,它不需要是塊長度的倍數(或者至少我認爲)。我將在今天晚些時候發佈文檔中的一些示例代碼:) –