对于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('/','_');
答案 0 :(得分:33)
修改后的Base64(替换/
,=
和+
时)可以安全地创建名称,但由于许多文件系统和URL不区分大小写,因此无法保证反向转换。 / p>
Base64区分大小写,因此在不区分大小写的文件系统(所有Windows文件系统,忽略POSIX子系统情况)的情况下,它不保证一对一映射。大多数网址也不区分大小写,阻止了1对1的映射。
在这种情况下我会使用Base32 - 你会得到更长的名字,但Base32编码的值对于文件/ uri的使用是100%安全的,无需替换任何字符,即使在不敏感的情况下也能保证1对1的映射环境(FAT / Win32 NTFS访问)。
不幸的是,在框架中通常没有对此编码的内置支持。另一方面,自己编写或在线查找代码相对简单。
答案 1 :(得分:10)
RFC 3548建议不仅要替换/
字符。 URL和文件名安全字母替换:
/
_
字符
+
的62:-
字符。但也许你最好使用HEX-String。有一段时间,我将哈希值存储在文件名中。我开始使用Base64 String,但切换到Hex-String。我不记得我为什么要切换,也许是因为Windows在'a'和'A'之间没有区别,正如AndiDog所说。
答案 2 :(得分:10)
我不确定您使用的编码是什么,但请考虑percent encoding文件名。
答案 3 :(得分:3)
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
答案 4 :(得分:2)
通常MD5哈希值(通常为哈希值)表示为十六进制字符串而不是Base64,后者只包含[a-f0-9]。所有文件系统都支持这些名称。
如果你真的想使用Base64,你的解决方案(替换斜杠)将无法正常工作,因为Windows文件系统在'A'和'a'之间没有区别。也许你想用Base32代替?但请注意,Base32在4中有8位,因此更容易采用十六进制表示。
通常,Windows和/或Linux中不允许使用以下字符:\ /:*? “<> |
答案 5 :(得分:1)
如果您使用与/不同的字符,则Base64创建的文件名是安全的,因为NTFS不允许在文件名中使用该字符。只要你这样做,几乎常见的all commonly used file systems就可以了。
但是,如果文件系统不区分大小写(如Windows上的情况),则可能会发生冲突,因为Base64字母包含大写和小写。
您可能需要考虑使用MD5哈希的十六进制表示,因为这是将它们表示为字符串的相当标准的方式。