1. ホーム
  2. regex

[解決済み] Base64 データを解析または検証するための RegEx

2022-09-07 06:08:13

質問

RegEx を使用して Base64 データを検証したり、サニタイズしたりすることは可能ですか? これは単純な質問ですが、この質問の原動力となる要因は、それを困難にしているものです。

私は、RFC 仕様に従うために入力データに完全に依存することができない Base64 デコーダーを持っています。 つまり、私が直面する問題は、Base64 データが 78 文字の行に分割されていない可能性がある (78 文字だと思いますが、RFC を再確認する必要があるので、正確な数が間違っていても私を責めないでください)、または行が CRLF で終わっていないかもしれない、つまり CR または LF のみ、あるいはどちらもないかもしれない、というような問題です。

このようにフォーマットされた Base64 データをパースするのに大変な苦労をしました。 このため、次のような例では、確実にデコードすることが不可能になっています。 簡潔にするために、MIME ヘッダーの一部のみを表示することにします。

Content-Transfer-Encoding: base64

VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu

OK、ではこれをパースするのは問題なく、まさに期待通りの結果です。 そして99%の場合、バッファ内の各文字が有効なbase64文字であることを少なくとも確認するためのコードを使用すれば、完璧に動作します。 しかし、次の例では、ミックスに一石を投じることになります。

Content-Transfer-Encoding: base64

http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu

これは、本というか RFC に厳密に従うメールリーダーに対して、何としてでも mime を解析したいというメールリーダーの欲望を利用しようとするウイルスやその他のものに見られる Base64 エンコーディングのバージョンです。

私の Base64 デコーダーは、2 番目の例を次のようなデータ ストリームにデコードします。 ここで、元のストリームはすべて ASCII データであることに留意してください!

[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8

どなたか、両方の問題を一度に解決する良い方法をご存じですか? 異なるルールを適用したデータに対して 2 つの変換を行い、その結果を比較すること以外、それが可能かどうかさえわかりません。 しかし、そのような方法を取った場合、どちらの出力を信用すればいいのでしょうか? ASCIIのヒューリスティックは約 ベスト しかし、このコードが実際に関与しているウイルス スキャナーのような複雑なものに、どれだけ多くのコード、実行時間、複雑さを追加することになるでしょうか? 許容可能な Base64 とそうでないものを学習するために、ヒューリスティック エンジンをどのように訓練するのでしょうか?


UPDATEです。

この質問の閲覧数が多いので、私が3年前からC#アプリケーションで使用している、数十万トランザクションの簡単なRegExを投稿することにしました。 正直なところ、私は次のような答えが好きです。 ガンボ が出した答えが一番好きで、それが選択された答えに選ばれた理由です。 しかし、C# を使用していて、少なくとも文字列または byte[] が有効な Base64 データを含むかどうかを検出する非常に迅速な方法を探している人には、次の方法が非常によく機能することがわかりました。

[^-A-Za-z0-9+/=]|=[^=]|={3,}$

そして、そう、これは単に STRING であり、適切にフォーマットされた RFC1341 メッセージではありません。 したがって、このタイプのデータを扱っている場合は、上記の RegEx を使用する前にそれを考慮してください。 もしあなたが他の目的 (URL、ファイル名、XML エンコードなど) で Base16、Base32、Radix、あるいは Base64 を扱っているなら、それは 非常に を読むことをお勧めします。 RFC4648 その ガンボ この質問と回答のセットにある提案を使おうとする前に、実装によって使用される文字セットとターミネータをよく理解する必要があるからです。

どのように解決するのですか?

からの RFC 4648 :

<ブロッククオート

データのベースエンコーディングは、おそらくレガシーな理由からUS-ASCIIデータに制限されている環境でのデータの保存や転送のために、多くの状況で使用されます。

つまり、データを危険と見なすべきかどうかは、エンコードされたデータの使用目的次第ということです。

ただ、Base64でエンコードされた単語にマッチする正規表現を探すのであれば、以下のようなものがあります。

^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$