11

[更新] 我为此提供奖金。坦率地说,我不在乎使用哪种加密方法。最好是一些简单的东西,比如 XTEA、RC4、BlowFish ......但你选择了。

我希望尽我所能,最好只是将文件放入我的项目并构建。

理想情况下,您应该已经使用该代码在 Delphi 和 C 中加密/解密文件(我想在 Atmel UC3 微处理器(用 C 编码)和 Windows PC(用 Delphi 编码)之间交换文件 en-and -de-crypt 双向)。

非常喜欢单个 .PAS 单元和单个 .C/.H 文件。我不想使用支持数十种加密算法的 DLL 或库,只有一种(我当然不想要任何带有安装程序的东西)。

我希望我在这里听起来不要太挑剔,但是我已经在谷歌上搜索并尝试了一个多星期的代码,但仍然找不到两个匹配的实现。我怀疑只有已经这样做的人才能帮助我......

提前致谢。


作为我上一篇文章的后续,我仍在寻找一些非常简单的代码,说明为什么我可以 - 以最小的努力 - 对文件进行加密并在 PC 上的 Delphi 和 Atmel UC3 u 处理器上的 C 之间交换它.

这在理论上听起来很简单,但在实践中却是一场噩梦。有很多可能的候选人,我花了几天时间谷歌搜索并尝试他们 - 无济于事。

有些是很有趣的库,支持许多加密算法,我想要一些轻量级的东西(尤其是在 C/u 处理器端)。

有些看起来不错,但一组源只提供块操作,其他字符串(我更喜欢整个文件加密/解密)。

大多数似乎都记录得很差,参数名称毫无意义,也没有调用函数的示例代码。

在过去的周末(再加上几天),我已经完成了大量的 XTEA、XXTEA 和 BlowFish 实现,但是虽然我可以加密,但我无法逆转这个过程。

现在我正在研究 AES-256。有谁知道 C 中的实现是单个 AES.C 文件吗?(当然还有 AES.H)

坦率地说,我会采取任何可以在 Delphi 和 C 之间进行整个文件加密/解密的事情,但是除非有人自己真正做到了这一点,否则我希望只听到“任何符合标准的实现都应该这样做”——这很好理论,但只是不适合我:-(

那里有任何简单的 C AES-256 吗?我有一些看起来很合理的 Delphi 代码,但直到我一起尝试后才能确定。

提前致谢 ...

4

6 回答 6

2

我建议在辅助微控制器(例如 Atmel SAM7X)上使用.NET Micro Framework作为加密协处理器。您可以在Netduino上进行测试,价格约为 35 美元/30 英镑。该框架在其命名空间下包含一个 AES 实现System.Security.Cryptography,以及可能对您有用的各种其他加密函数。这样做的好处是您获得了经过全面测试和工作的实现,并通过类型安全代码提高了安全性。

如果需要更高的吞吐量,您可以使用 SPI 或 I2C 在两个微控制器之间进行通信,或者通过多条 I/O 线并行地对您自己的数据传输协议进行位转换。

我使用 Arduino 和 Netduino(使用 Netduino 对硬件 BitTorrent 设备的数据块进行哈希处理)完全做到了这一点,并使用通过 SPI 和中断机制在设备之间发送的各种命令实现了一个基本的异步系统。

  • Arduino 是 SPI 主机,Netduino 是 SPI 从机。
  • Netduino 上的一个 GPIO 引脚设置为输出,并连接到Arduino 上另一个启用中断的 GPIO 引脚,该引脚设置为输入。这是中断引脚。
  • Arduino0xF1作为“hello”初始化消息发送。
  • Netduino0xF2作为确认发回。
  • 当 Arduino 想要散列一个块时,它会发送0x48(ASCII 'H') 后跟数据。当它完成发送数据时,它设置为CS低。它必须发送整个字节;CS当接收到的位数不能被 8 整除时设置为低会导致错误。
  • Netduino 接收数据,然后将0x68接收到的字节数作为 2 字节无符号整数发回(ASCII 'h')。如果发生错误,它会发回0x21(ASCII '!')。
  • 如果成功,Netduino 会计算哈希值,然后将中断引脚设置为高电平。在计算期间,Arduino 可以在等待期间自由地继续其工作。
  • Arduino 发送0x52(ASCII 'R')来请求结果。
  • Netduino 将中断引脚设置为低电平,然后发0x72回(ASCII 'r')和原始哈希数据。

由于 Arduino 可以通过 GPIO 引脚处理中断,因此我可以使处理完全异步。Arduino 端的一个变量跟踪我们当前是否正在等待协处理器完成其任务,因此我们不会尝试在它仍在处理旧块时向它发送新块。

您可以轻松地调整此方案来计算 AES 块。

于 2012-12-10T11:43:31.683 回答
2

Ilya Levin的 AES-256 小型 C 库。实现简短,无汇编,使用简单。不过,不确定它如何在您当前的微型 CPU 上工作。

[编辑]
你提到有一些 delphi 实现,但如果某些东西不能一起工作,试试thisthis
我还发现了使用 Ilya 库的 arduino(基于 avr)模块 - 所以它也应该在你的微型 CPU 上工作。

于 2012-12-19T03:28:05.450 回答
2

你能从Delphi编译C代码吗(你可以从C++ Builder编译Delphi代码,不确定VV)。或者也许使用免费的 Borland 命令行 C++ 编译器,甚至是另一个 C 编译器。

这个想法是在您的 Windows 应用程序中使用与在微处理器上使用相同的 C 代码。这样您可以合理地确定代码将在两个方向上工作。


[更新] 见

http://www.drbob42.com/examines/examin92.htm
http://www.hflib.gov.cn/e_book/e_book_file/bcb/ch06.htm (在Delphi中使用C++代码)
http://edn.embarcadero .com/article/10156#H11

看起来你需要使用一个 DLL,但如果你不想分发它,你可以静态链接它

于 2012-12-19T04:51:07.383 回答
1

看起来更容易获得参考 AES 实现(与块一起使用),并添加一些代码来处理 CBC(或 CTR 加密)。您只需添加约 30-50 行代码,如下所示(对于 CBC):

aes_expand_key();

first_block = iv;

for (i = 0; i < filesize / 16; i++)
{
  data_block = read(file, 16);
  data_block = (data_block ^ iv);
  iv = encrypt_block(data_block);
  write(outputfile, iv);  
}

// if filesize % 16 != 0, then you also need to add some padding and encrypt the last block
于 2012-12-10T14:09:25.077 回答
1

这是RC4代码。它非常轻巧。

C 已经在生产系统中使用了五年。

我添加了经过轻微测试的 Delphi 代码。unsigned charPascal 是一个带有go to的逐行端口Byte。我只在打开了 Delphi 选项的 Free Pascal 中运行 Pascal,而不是 Delphi 本身。C 和 Pascal 都有简单的文件处理器。

对密文进行加扰会返回原始的明文。

迄今为止没有报告任何错误。希望这能解决您的问题。

rc4.h

#ifndef RC4_H
#define RC4_H

/*
 * rc4.h -- Declarations for a simple rc4 encryption/decryption implementation.
 * The code was inspired by libtomcrypt.  See www.libtomcrypt.org.
 */
typedef struct TRC4State_s {
  int x, y;
  unsigned char buf[256];
} TRC4State;

/* rc4.c */
void init_rc4(TRC4State *state);
void setup_rc4(TRC4State *state, char *key, int keylen);
unsigned endecrypt_rc4(unsigned char *buf, unsigned len, TRC4State *state);

#endif

rc4.c

void init_rc4(TRC4State *state)
{
  int x;
  state->x = state->y = 0;
  for (x = 0; x < 256; x++)
    state->buf[x] = x;
}

void setup_rc4(TRC4State *state, char *key, int keylen)
{
  unsigned tmp;
  int x, y;

  // use only first 256 characters of key 
  if (keylen > 256) 
    keylen = 256;

  for (x = y = 0; x < 256; x++) {
    y = (y + state->buf[x] + key[x % keylen]) & 255;
    tmp = state->buf[x]; 
    state->buf[x] = state->buf[y]; 
    state->buf[y] = tmp;
  }
  state->x = 255;
  state->y = y;
}

unsigned endecrypt_rc4(unsigned char *buf, unsigned len, TRC4State *state)
{
  int x, y; 
  unsigned char *s, tmp;
  unsigned n;

  x = state->x;
  y = state->y;
  s = state->buf;
  n = len;
  while (n--) {
    x = (x + 1) & 255;
    y = (y + s[x]) & 255;
    tmp = s[x]; s[x] = s[y]; s[y] = tmp;
    tmp = (s[x] + s[y]) & 255;
    *buf++ ^= s[tmp];
  }
  state->x = x;
  state->y = y;
  return len;
}

int endecrypt_file(FILE *f_in, FILE *f_out, char *key)
{
  TRC4State state[1];
  unsigned char buf[4096];
  size_t n_read, n_written;

  init_rc4(state);
  setup_rc4(state, key, strlen(key));
  do {
    n_read = fread(buf, 1, sizeof buf, f_in);
    endecrypt_rc4(buf, n_read, state);
    n_written = fwrite(buf, 1, n_read, f_out);
  } while (n_read == sizeof buf && n_written == n_read);
  return (n_written == n_read) ? 0 : 1;
}

int endecrypt_file_at(char *f_in_name, char *f_out_name, char *key)
{
  int rtn;

  FILE *f_in = fopen(f_in_name, "rb");
  if (!f_in) {
    return 1;
  }
  FILE *f_out = fopen(f_out_name, "wb");
  if (!f_out) {
    close(f_in);
    return 2;
  }
  rtn = endecrypt_file(f_in, f_out, key);
  fclose(f_in);
  fclose(f_out);
  return rtn;
}

#ifdef TEST

// Simple test.
int main(void)
{
  char *key = "This is the key!";

  endecrypt_file_at("rc4.pas", "rc4-scrambled.c", key);
  endecrypt_file_at("rc4-scrambled.c", "rc4-unscrambled.c", key);
  return 0;
}
#endif

这是经过轻微测试的帕斯卡。我可以对 C 中的源代码进行加扰,并使用 Pascal 实现对其进行解扰。

type
  RC4State = record
    x, y : Integer;
    buf : array[0..255] of Byte;
  end;

  KeyString = String[255];

procedure initRC4(var state : RC4State);
var
  x : Integer;
begin
  state.x := 0;
  state.y := 0;
  for x := 0 to 255 do
    state.buf[x] := Byte(x);
end;

procedure setupRC4(var state : RC4State; var key : KeyString);
var
  tmp : Byte;
  x, y : Integer;
begin
  y := 0;
  for x := 0 to 255 do begin
    y := (y + state.buf[x] + Integer(key[1 + x mod Length(key)])) and 255;
    tmp := state.buf[x];
    state.buf[x] := state.buf[y];
    state.buf[y] := tmp;
  end;
  state.x := 255;
  state.y := y;
end;

procedure endecryptRC4(var buf : array of Byte; len : Integer; var state : RC4State);
var
  x, y, i : Integer;
  tmp : Byte;
begin
  x := state.x;
  y := state.y;
  for i := 0 to len - 1 do begin
    x := (x + 1) and 255;
    y := (y + state.buf[x]) and 255;
    tmp := state.buf[x];
    state.buf[x] := state.buf[y];
    state.buf[y] := tmp;
    tmp := (state.buf[x] + state.buf[y]) and 255;
    buf[i] := buf[i] xor state.buf[tmp]
  end;
  state.x := x;
  state.y := y;
end;

procedure endecryptFile(var fIn, fOut : File; key : KeyString);
var
  nRead, nWritten : Longword;
  buf : array[0..4095] of Byte;
  state : RC4State;
begin
  initRC4(state);
  setupRC4(state, key);
  repeat
    BlockRead(fIN, buf, sizeof(buf), nRead);
    endecryptRC4(buf, nRead, state);
    BlockWrite(fOut, buf, nRead, nWritten);
  until (nRead <> sizeof(buf)) or (nRead <> nWritten);
end;

procedure endecryptFileAt(fInName, fOutName, key : String);
var
  fIn, fOut : File;
begin
  Assign(fIn, fInName);
  Assign(fOut, fOutName);
  Reset(fIn, 1);
  Rewrite(fOut, 1);
  endecryptFile(fIn, fOut, key);
  Close(fIn);
  Close(fOut);
end;

{$IFDEF TEST}
// Very small test.
const
  key = 'This is the key!';
begin
  endecryptFileAt('rc4.pas', 'rc4-scrambled.pas', key);
  endecryptFileAt('rc4-scrambled.pas', 'rc4-unscrambled.pas', key);
end.
{$ENDIF}
于 2012-12-19T04:59:35.990 回答
1

假设加密强度不是问题,如满足组织的中国墙要求,非常简单的“锯齿”加密方案将 (i++ % modulo 256) 添加到 fgetc(),对于每个字节,从开头开始文件,可能工作得很好。

将 i 声明为 UCHAR 将消除模数要求,因为单字节整数只能在 0-255 范围内循环。

代码太简单了,不值得发。一点点想象力,你就会有一些装饰,可以大大增加这个密码的强度。这种密码的主要漏洞是大块相同的字符。纠正这一点是开始提高其实力的好地方。

此密码适用于所有可能的文件类型,如果您已经对文件进行了 7Zip 压缩,则特别有效。

性能是惊人的。你甚至不知道代码在那里。完全 I/O 绑定。

于 2012-12-21T01:26:55.530 回答