我在 Rabbit 微处理器上使用动态 C编程语言。我相信 Dynamic C 基于 ANSI-C89 有一些非常细微的变化。他们有一个 AES 加密库,我试图在将数据发送到我的服务器之前使用它来加密数据(收效甚微)。
这是我正在使用的基于 C 的 AES 函数的文档:
AESinitStream
语法: void AESinitStream(AESstreamState *state, const char *key, const char *init_vector);
描述:设置流状态结构以开始加密或解密流。特定的流状态只能用于一个方向。
PARAMETER1: state - 要初始化的 AESstreamState 结构
PARAMETER2: key - 16 字节密码密钥,使用 NULL 指针将防止重新计算现有密钥。
PARAMETER3:init_vector - 一个 16 字节数组,表示反馈寄存器的初始状态。流的两端必须以相同的初始化向量和键开始。
AES加密流
语法:void AESencryptStream(AESstreamState *state, char *data, int count);
描述:加密一个字节数组
PARAMETER1: state - AESstreamState 结构
PARAMETER2: data - 将被加密的字节数组。
PARAMETER3: count - 数据数组的大小
这是我的 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
数据:249 78 60 83 130 167 37
四: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
数据:249 78 60 83 130 167 37
四:74 121 108 165 83 120 36 27 161 192 84 76 105 239 34 214
解密:t{^^?d2
如您所见,我的解密文本中出现了一些奇怪的输出。谁能指出我正确的方向?
我已经尝试使用 Dynamic C 成功解密,但是如果您认为内置的 Dynamic 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 个字节。我一无所知。
这是来自 Rabbit 的使用 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));