0

AES で暗号化され、base64 でエンコードされたファイルを PHP から C# クライアント (Mono、さまざまなプラットフォーム) に提供する必要があります。AES 暗号化/復号化は正常に機能しましたが、base64 エンコーディング/デコーディングを試みるとすぐに問題が発生します。以下の両方の例では、AES が無効になっているため、それは問題ではありません。

私の最も単純なテスト ケースである Hello World 文字列は正常に動作します。

PHP サービング出力 -

// Save encoded data to file
$data = base64_encode("Hello encryption world!!");
$file = fopen($targetPath, 'w');
fwrite($file, $data);
fclose($file);

// Later on, serve the file
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=".basename($product->PackageFilename($packageId)));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($targetPath));
ob_clean();
flush();
$handle = fopen($targetPath, "r");
fpassthru($handle);
fclose($handle);

C# のデコードと使用 -

StreamReader reader = new StreamReader(stream);
char[] buffer = DecodeBuffer;
string decoded = "";
int read = 0;
while (0 < (read = reader.Read(buffer, 0, DecodeBufferSize)))
{
    byte[] decodedBytes = Convert.FromBase64CharArray(buffer, 0, read);
    decoded += System.Text.Encoding.UTF8.GetString(decodedBytes);
}
Log(decoded); // Correctly logs "Hello encryption world!!"

ただし、ファイルの内容で同じことをしようとすると、 Convert.FromBase64CharArray によってFormatException: Invalid character foundがスローされます。

PHP サービング出力 -

// Save encoded data to file
$data = base64_encode(file_get_contents($targetPath));
$file = fopen($targetPath, 'w');
fwrite($file, $data);
fclose($file);

// Later on, serve the file
// Same as above

C# のデコードと使用 -

using (Stream file = File.Open(zipPath, FileMode.Create))
{
using (StreamReader reader = new StreamReader(stream))
{
    char[] buffer = DecodeBuffer;
    byte[] decodedBytes;
    int read = 0;
    while (0 < (read = reader.Read(buffer, 0, DecodeBufferSize)))
    {
        // Throws FormatException: Invalid character found
                    decodedBytes = Convert.FromBase64CharArray(buffer, 0, read);
        file.Write(decodedBytes, 0, decodedBytes.Length);
    }
}
}

base64 を有効にするために、より大きなデータに対して何らかの追加処理を行う必要がありますか? おそらく、大きなバイナリ データでこれを行うのは適切ではないのでしょうか?もしそうなら、送信するのに安全でない文字による潜在的な問題をどのように防ぐことができますか?

4

2 に答える 2

1

読んでいるBase64テキストコードが正しくありません。

  • Base64はテキストなので、代わりにテキストリーダーの使用を検討してください
  • Base64には、新しい行/空白が含まれる場合があります。つまり、Base64でエンコードされた値全体を70〜80文字の長さの文字列に分割するのが習慣です。

ファイル内のデータが正しいかどうかを確認するには、ファイル全体を文字列(StreamReader.ReadToEnd)として読み取り、バイト配列(Convert.FromBase64String)に変換します。

ファイルに有効なBase64データが含まれていて、それを単一の文字列として読み取ることができない場合は、独自のBase64デコードを実装するか、正しい数の非空白文字(4の倍数)を手動で読み取り、そのようなチャンクをデコードする必要があります。

于 2012-04-09T17:02:02.640 に答える
1

Base64エンコードは、3オクテットを4エンコード文字に変換します。したがって、デコード用に提供するデータの長さは4の倍数である必要があります。

まず、それDecodeBufferSizeが4の倍数であることを確認します。次に、StreamReader.Read要求されたすべてのバイトが読み取られることを保証するものではないため、バイトがbufferいっぱいになるか、ストリームの終わりに達するまで読み取りを続ける必要があります。

于 2012-04-09T17:03:00.333 に答える