WindowsおよびLinuxシステムのファイル名にBase64エンコーディングを使用しても安全ですか?私の調査から、結果のすべての/
文字を-
または_
に置き換えると問題が解決することがわかりました。
誰もがこれについてより詳細を提供できますか?
現在Java私は次のコードを使用しています:
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
md5Digest.reset();
md5Digest.update(plainText.getBytes());
byte[] digest = md5Digest.digest();
BASE64Encoder encoder = new BASE64Encoder();
hash = encoder.encode(digest);
hash.replace('/','_');
変更されたBase64(/
、=
および+
は置き換えられます)名前を作成しても安全ですが、多くのファイルシステムとURLで大文字と小文字が区別されないため、逆変換は保証されません。
Base64は大文字と小文字を区別するので、大文字と小文字を区別しないファイルシステム(すべてのWindowsファイルシステム、POSIXサブシステムの場合を無視)の場合、1対1のマッピングは保証されません。ほとんどのURLは大文字と小文字を区別せず、1対1のマッピングを防止します。
この場合はBase32を使用します。名前はもう少し長くなりますが、Base32エンコードされた値は、文字を置き換えずにファイルやURIを使用する場合に100%安全であり、無感覚な環境(FAT/Win32 NTFSアクセス)。
残念ながら、通常、フレームワークではこのエンコーディングの組み込みサポートはありません。一方、コードは自分で書いたりオンラインで見つけたりするのが比較的簡単です。
エンコーディングを何に使用しているのかはわかりませんが、 パーセントエンコーディング ファイル名を検討してください。
RFC 3548 は、/
文字を置き換えるだけでなく、 URLとファイル名を安全にアルファベットで置き換えます:
/
文字とアンダースコア_
+
文字とマイナス-
。しかし、多分あなたはより良い16進文字列を使用します。ファイル名にハッシュ値を格納するのは久しぶりです。私はBase64文字列の使用から始めましたが、16進数文字列に切り替えました。 AndiDogが言ったように、Windowsが 'a'と 'A'を区別しないためか、なぜ切り替えたのか覚えていません。
C#のワンライナー:
String filename = Convert.ToBase64String(new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes("UTF-8 string with snowmen"))).Replace("+", "_").Replace("/", "-").Replace("=","");
ファイルの先頭に次のものが必要です:
using System.Security.Cryptography
using System.Text
通常、MD5ハッシュ(一般にハッシュ)は、Base64ではなく16進数の文字列として表され、[a-f0-9]のみが含まれます。これらの名前はすべてのファイルシステムでサポートされます。
本当にBase64を使用したい場合、Windowsのファイルシステムでは「A」と「a」の違いが生じないため、ソリューション(スラッシュの置換)は正しく機能しません。代わりにBase32を使用したいですか?ただし、Base32は4から8ビットを生成するため、16進数表現を使用する方が簡単です。
一般に、次の文字はWindowsやLinuxでは使用できません:\ /:*? "<> |
NTFSではファイル名にその文字を使用できないため、Base64によって作成されたファイル名は、/とは異なる文字を使用する場合にのみ安全です。そうする限り、一般的に使用されている すべての一般的に使用されるファイルシステム で問題ありません。
ただし、Windowsの場合のように、ファイルシステムがcase-insensitiveの場合、Base64アルファベットには大文字と小文字の両方が含まれているため、衝突が発生する可能性があります。 。
これはMD5ハッシュの16進数表現の使用を検討することをお勧めします。これは、これを文字列として表現するかなり標準的な方法だからです。