これは重複した投稿ではありません。なぜなら、私はどこを見ても答えが見つからないからです。その部分的な復号化について。満タンではない。
PHP についてはよく知っていますが、暗号化についてはほとんど知りません。暗号化されたファイルのキーと iv を知っています。ファイル全体は正常に復号化されていますが、途中から部分的なファイルを復号化しようとすると、実際の問題が発生します。
ファイルの最初の 128kb または 256kb またはファイルの先頭から任意の長さを復号化しようとすると、正常に復号化されます。しかし、途中から開始すると、復号化されず、意味不明な出力が得られます。
ファイルの最初の 100 バイトの例をここに投稿します。
暗号化は AES 128 ビット CTR モードです。
PHP の mdecrypt_generic 関数と mcrypt_decrypt 関数の両方を使用しましたが、成功しませんでした。
使用したコード:
$chunk2 = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, base64_decode($mega_key), $data, 'ctr', base64_decode($mega_iv));
echo base64_encode($data) .'<br />'. base64_encode($chunk2);
結果:
9PX2fU83NF3hLc+HFdyHkqfxC4bHWKUQwQHJkNVnYbKCIQrhlHvTKtz8T3Bb0TgBkyBoGHnDCzZs3bu54KLQ8Bv0lzrTVJbzJY5msBfcy7Zi2Z/fLoMm+nvqdGPTNR0uwv45xJ8=
MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTE=
ご覧のように。復号化後の結果は、数字の 1が連続して含まれるファイルの最初の 100 バイトです。ファイルは JavaScript を使用して Mega.co.nz によって暗号化されます。Mega のドキュメントによると、ファイルは部分的な暗号化/復号化のためにチャンクで暗号化されています。
ファイル暗号化
MEGA は、クライアント側の暗号化/復号化を使用して、ファイル転送とストレージをエンドツーエンドで保護します。クライアントから受信したデータは保存され、逐語的に送信されます。サーバーは、着信ユーザー ファイルの暗号化を復号化も再暗号化も検証もしません。すべての暗号化処理は、エンド ユーザーの管理下にあります。整合性がチェックされた部分読み取りを可能にするために、ファイルは一連のチャンクとして扱われます。サーバー側の処理を簡素化するために、部分アップロードはチャンク境界でのみ開始および終了できます。さらに、部分的なダウンロードは、同じ基準を満たす場合にのみ完全性をチェックできます。チャンク境界は、0 / 128K / 384K / 768K / 1280K / 1920K / 2688K / 3584K / 4608K / の位置にあります。(1024 KB ごと) / EOF
この関数を使用して、ファイルのチャンク境界を計算しています。
public function get_chunks($size)
{
$chunks = array();
$p = $pp = 0;
for ($i = 1; $i <= 8 && $p < $size - $i * 0x20000; $i++) {
$chunks[$p] = $i * 0x20000;
$pp = $p;
$p += $chunks[$p];
}
while ($p < $size) {
$chunks[$p] = 0x100000;
$pp = $p;
$p += $chunks[$p];
}
$chunks[$pp] = ($size - $pp);
if (!$chunks[$pp])
{
unset($chunks[$pp]);
}
return $chunks;
}
2 番目のチャンクを個別に復号化しようとしましたが、失敗します。明らかな理由で 128kb のチャンクをここに投稿することはできませんが、2 バイト目から 100 バイト目までのチャンクを示します。これは同じコードの結果です:
使用したコード:
$chunk2 = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, base64_decode($mega_key), $data, 'ctr', base64_decode($mega_iv));
echo base64_encode($data) .'<br />'. base64_encode($chunk2);
結果:
9fZ9Tzc0XeEtz4cV3IeSp/ELhsdYpRDBAcmQ1WdhsoIhCuGUe9Mq3PxPcFvROAGTIGgYecMLNmzdu7ngotDwG/SXOtNUlvMljmawF9zLtmLZn98ugyb6e+p0Y9M1HS7C/jnEnw==
MDK6A0kyWI3903mj+GokBGfLvHCuzITg8flodIM34gGSGtpE3pnIxxGCDhq72AijgnlBUIv5DGuAVzNoc0MR2t5SnNi281TnmtnnlvomTOWKd3HAnJTtsKCvJoHXGQLdDfbMag==
結果は同じですmcrypt_module_open('rijndael-128', '', 'ctr', '');
並列接続/再開サポートをサポートする Mega 用のオープン ソース ダウンロード マネージャーをコーディングしようとしているため、ファイルを部分的に復号化する必要があります。
ファイルのストリーミングを許可するには、その場でファイルを復号化する必要があるため、ダウンロード後に復号化することは問題外です。
Mega の Web サイトでは、独自のダウンロード インターフェイスが複数の接続を使用し、ファイルをチャンクでダウンロードします。複数の接続を使用して Mega からダウンロードし、サポートを再開できる別の Web サービスがあります。
ブラウザ/ダウンロード マネージャからの HTTP Range ヘッダー リクエストをサポートするには、部分ファイルを復号化する必要があります。範囲要求が 2 番目または 3 番目のブロックに含まれる場合、最初からファイルを復号化せずに、そのブロックを復号化してクライアントに送信できる必要があります。
それは可能ですか?一部のWebサイトがすでにそれを行っているためです。