11

【追記】特典をお付けします。率直に言って、どの暗号化方式が使用されているかは気にしません。できれば XTEA、RC4、BlowFish のようなシンプルなものを選びましたが、あなたはそれを選びました。

私は自分の労力を最小限に抑えたいと思っています。できれば、ファイルをプロジェクトにドロップしてビルドするだけです。

理想的には、コードを使用して、Delphi と C でファイルを暗号化/復号化している必要があります (Atmel UC3 マイクロプロセッサ (C でコーディング) と Windows PC (Delphi でコーディング) の間でファイルを交換したい) -両方向で復号化します)。

私は単一の .PAS ユニットと単一の .C/.H ファイルを強く好みます。私は DLL や、1 つだけの数十の暗号化アルゴリズムをサポートするライブラリを使用したくありません (もちろん、インストール プログラムには何も必要ありません)。

ここでうるさく聞こえないことを願っていますが、1週間以上グーグルでコードを試してみましたが、一致する2つの実装がまだ見つかりません。すでにこれを行った人だけが私を助けることができると思います...

前もって感謝します。


私の以前の投稿のフォローアップとして、私はまだいくつかの非常に単純なコードを探しています.なぜ最小限の労力でファイルを暗号化解除し、PC上のDelphiとAtmel UC3 u-processor上のCの間でそれを交換できますか. .

理論的には簡単に思えますが、実際には悪夢です。多くの候補があり、私は何日もグーグルで検索して試してみましたが、役に立ちませんでした。

いくつかは巨大なライブラリで、多くの暗号化アルゴリズムをサポートしており、軽量なものが必要です (特に C/u プロセッサ側で)。

一部は良さそうに見えますが、ソースの 1 つのセットはブロック操作のみを提供し、その他の文字列は提供します (ファイル全体の暗号化/復号化を希望します)。

ほとんどは、意味のないパラメーター名と関数を呼び出すためのコード例がないため、文書化が不十分であるようです。

先週末 (さらに数日) にわたって、私は XTEA、XXTEA、および BlowFish の多数の実装を焼き尽くしましたが、暗号化はできても、プロセスを元に戻すことはできません。

今、私はAES-256を見ています。単一の AES.C ファイルである C での実装を知っている人はいますか? (もちろん、AES.Hも)

率直に言って、私は Delphi と C の間でファイル全体の暗号化/復号化を行うものは何でも採用しますが、実際にこれを自分で行った人がいない限り、「標準を満たす実装であれば行うべき」という意見しか聞かれないと思います。理論的ですが、私にとってはうまくいきません:-(

C の単純な AES-256 はありますか? 私は合理的に見える Delphi コードをいくつか持っていますが、それらを一緒に試してみるまで確信が持てません。

前もって感謝します ...

4

6 に答える 6

2

Delphi から C コードをコンパイルできますか (C++ Builder から Delphi コードをコンパイルできますが、VV についてはわかりません)。または、無料の Borland Command line C++ コンパイラまたは別の C コンパイラを使用することもできます。

アイデアは、マイクロプロセッサで使用するのと同じ C コードを Windows アプリで使用することです。そうすれば、コードが双方向で機能することを合理的に確信できます。


【更新】参照

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 に答える
2

セカンダリ マイクロコントローラー (Atmel SAM7X など) で.NET Micro Frameworkを暗号化コプロセッサーとして使用することをお勧めします。これはNetduinoでテストできます。約 35 ドル / 30 ポンドで購入できます。このフレームワークには、名前空間の下に AES 実装が含まれており、System.Security.Cryptography便利なその他のさまざまな暗号化機能も含まれています。ここでの利点は、完全にテストされて機能する実装が得られ、タイプ セーフ コードによってセキュリティが強化されることです。

SPI または I2C を使用して 2 つのマイクロコントローラー間で通信するか、より高いスループットが必要な場合は、複数の I/O ラインで並列に独自のデータ転送プロトコルをビットバンすることができます。

私は Arduino と Netduino (Netduino を使用してハードウェア BitTorrent デバイスのデータ ブロックをハッシュする) でこれを正確に行い、SPI と割り込みメカニズムを介してデバイス間で送信されるさまざまなコマンドを使用して、基本的な非同期システムを実装しました。

  • Arduino は SPI マスター、Netduino は SPI スレーブです。
  • Netduino の GPIO ピンは出力として設定され、入力として設定された Arduino の別の割り込み対応 GPIO ピンに接続されます。これは割り込みピンです。
  • Arduino0xF1は「hello」初期化メッセージとして送信します。
  • Netduino0xF2は、確認として返信します。
  • Arduino がブロックをハッシュする場合、0x48(ASCII 'H') に続いてデータを送信します。データの送信が完了すると、CSLow に設定されます。バイト全体を送信する必要があります。CS受信ビット数が 8 で割り切れない場合に Low に設定すると、エラーが発生します。
  • Netduino はデータを受信し、0x68(ASCII 'h') に続いて受信したバイト数を 2 バイトの符号なし整数として送り返します。エラーが発生した場合は、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 ライブラリ。短い実装、asm レス、簡単な使用法。ただし、現在のマイクロ CPU でどのように機能するかはわかりません。

[編集] Delphi の実装について言及しましたが、何かがうまくいかない場合は、これまたはこれ
を試してください。 また、Ilya のライブラリを使用する arduino (avr ベース) モジュールを見つけたので、マイクロ CPU でも動作するはずです。

于 2012-12-19T03:28:05.450 に答える
1

組織のChineseWall要件を満たす場合のように、暗号化の強度が問題ではないと仮定すると、バイトごとに(i ++%modulo 256)をfgetc()に追加する、非常に単純な「Sawtooth」暗号化スキームが、ファイル、問題なく動作する可能性があります。

iをUCHARとして宣言すると、1バイト整数は0〜255の範囲を循環せざるを得ないため、モジュロ要件がなくなります。

コードはとても単純なので、投稿する価値はありません。少し想像力を働かせれば、このサイファーの強さを大幅に高めることができる装飾がいくつかあります。このサイファーの主な脆弱性は、同一の文字の大きなブロックです。これを修正することは、その強度を改善し始めるのに良い場所です。

この暗号は、考えられるすべてのファイルタイプで機能し、ファイルをすでに7ZIPしている場合に特に効果的です。

パフォーマンスは驚異的です。コードがそこにあることすらわかりません。完全にI/Oバウンド。

于 2012-12-21T01:26:55.530 に答える
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 は、本番システムで 5 年間使用されています。

軽くテストした Delphi コードを追加しました。Pascal は行単位の移植であり、 with unsigned chargoing to Byte. Delphi自体ではなく、DelphiオプションをオンにしてFree PascalでPascalを実行しただけです。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

これは軽くテストされた Pascal です。ソース コードを 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 に答える