2012-11-13 6 views
5

CESモードのAESアルゴリズムでデータを暗号化しようとしています。この理由から私は.Netライブラリ 'Bouncy Castle'を使用します。私は暗号の背景を持っていないので、私はそれを簡単な方法で使用しようとしています。ここに私の暗号化コードがありますbouncyCastleで暗号化する前にデータを埋め込む方法

public byte[] encrypt(byte[] key, byte[] iv,byte[] data) 
    { 
     IBlockCipher engine=new AesFastEngine(); 
     KeyParameter keyParam = new KeyParameter(key); 
     CbcBlockCipher cipher = new CbcBlockCipher(engine); 

     ICipherParameters parameters = new ParametersWithIV(keyParam, iv); 

     byte[] output=new byte[16+data.Length]; 
     cipher.Init(true, parameters); 
     cipher.ProcessBlock(data, 0, output, data.Length); 

     //process output 
     byte[] cipherArray = new byte[data.Length]; 
     /* 
     int k=0; 
     for (int i = 0; i < output.Length; i++) 
     { 
      if (output[i]!= 0) 
      { 
       cipherArray[k++] = output[i]; 
      } 
     } 
     */ 
     return cipherArray; 

    } 

16の倍数ではない入力を試してみると、例外が発生します。私が左に0を付けた数(16-長さ%16)で右に配列をパディングすると結果が得られます。しかし結果は私にとっても問題です。それは私にこのような結果を与える:

[0][0][0][0[111][22][33][44][66][77][33][12][32][23][0][0][0][0][0] 

ゼロの左右両方に。

私はProcessBlock(data, 0, output, data.Length)機能を使用している可能性があると思っていました。出力は暗号化されたテキストになるという前提で使用しますが、出力は入力長より長くする必要があります。この関数に関するドキュメントがないので、間違った方法で使用している可能性があります。任意のヘルプはアプリケーションになるでしょう

答えて

4

弾む城は、あなたのためのパディングを行いますあなたのcihperを設定する必要が開始するよう:そう

PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); 
cipher.GetOutputSize(data.Length) ProcessBytesを使用する必要があります動作するようにあなたのコードの残りの部分については

、およびDoFinalパディングが正しく追加されます。

byte[] output = new byte[cipher.GetOutputSize(data.Length)]; 
int len = cipher.ProcessBytes(data, 0, data.Length, output, 0); 
cipher.DoFinal(output, len); 

私はAES-GCM in Bouncy Castle on CodeReview

AES-GCMを使用するのに簡単な例を持っているが、認証、暗号化が追加されますが、APIを使用しての基本的な原理は同じです。

Iはまた、高レベルの暗号化フレームワークのC#のポートを有するKecyzar、Iは、バックエンドとして弾む城を使用したこと、それは困難例ですが、抽象化された暗号化コードSymmetricStreamBouncyAesKey

+0

でAES-CBCを使用するための設定でありますどうもありがとう、私はpaddedCipher.DoFinal(出力、len)を使用しようとすると、このパターンに問題があります。 「最後のブロックが不完全である」という例外をスローします。processBytesメソッドは、データ長より小さい16の倍数を返します。この問題の原因は何ですか?ありがとう – ikbal

+0

@paskalnikov使用方法を示すためにコードを追加しました。'ProcessBytes'は完全なブロックごとにバイトを出力し、残りの部分をバッファし続けます(あなたは一度にいくつかのデータを与えたい場合に' ProcessBytes'を何度も呼び出すこともできます)。 'DoFinal'を呼び出すまで、' DoFinal'は最後のバイトを(パディング付きで)書き出します。そのため、最終出力配列に 'DoFinal'を書き込む場合は、書き込み先のインデックスを与える必要があります配列。 – jbtule

2

一般的に、標準のパディングアルゴリズムを使用して、プレーンテキストデータが暗号のブロックサイズに確実に揃うようにします。

現在のところ、zero paddingを手書きで入力しています。これは、ゼロバイトで終わる元のデータを禁止するので、大きな選択ではありません。どのようにパディングと区別することができますか?

PKCS #7 paddingのような標準のパッドを使用することをお勧めします。非常に似ているので、これはしばしば "PKCS#5パディング"と呼ばれることに注意してください。

この他のSOの質問Encrypt/Decrypt using Bouncy Castle in C#を参照して、標準的なパッドを使用する例があります。

関連する問題