【发布时间】:2016-09-24 18:53:21
【问题描述】:
我在 Rabbit 微处理器上使用Dynamic C 编程语言。我相信 Dynamic C 基于 ANSI-C89 有一些非常细微的变化。他们有一个 AES 加密库,我试图在将数据发送到我的服务器之前使用它来加密数据(收效甚微)。
这是我正在使用的基于 C 的 AES 函数的文档:
AESinitStream
语法:void AESinitStream(AESstreamState *state, const char *键, const char *init_vector);
描述:设置流状态结构以开始加密或 解密流。特定的流状态只能是 用于一个方向。
PARAMETER1: state - 要初始化的 AESstreamState 结构
PARAMETER2: key - 16 字节的密钥,使用 NULL 指针将防止 避免重新计算现有密钥。
PARAMETER3:init_vector - 表示初始状态的 16 字节数组 的反馈寄存器。流的两端必须 以相同的初始化向量和键开始。
AESencryptStream
语法:void AESencryptStream(AESstreamState *state, 字符 * 数据, 整数);
描述:加密字节数组
PARAMETER1:状态 - AESstreamState 结构
PARAMETER2:数据 - 将被加密的字节数组。
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 的示例代码的 sn-p(他们选择将 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,它不需要是块长度的倍数(或者至少我认为)。我将在今天晚些时候发布文档中的一些示例代码 :)
-
密文总是是 AES 中块大小的倍数。
-
@EugeneSh。加密数据不总是块大小的倍数,有几种模式不会产生块大小的倍数,包括 CTR 模式。
标签: c# c encryption aes dynamic-c