Base64编码对文件名安全吗?

时间:2010-10-15 19:42:50

标签: java hash encoding base64 filenames

对于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('/','_');

6 个答案:

答案 0 :(得分:33)

修改后的Base64(替换/=+时)可以安全地创建名称,但由于许多文件系统和URL不区分大小写,因此无法保证反向转换。 / p>

Base64区分大小写,因此在不区分大小写的文件系统(所有Windows文件系统,忽略POSIX子系统情况)的情况下,它不保证一对一映射。大多数网址也不区分大小写,阻止了1对1的映射。

在这种情况下我会使用Base32 - 你会得到更长的名字,但Base32编码的值对于文件/ uri的使用是100%安全的,无需替换任何字符,即使在不敏感的情况下也能保证1对1的映射环境(FAT / Win32 NTFS访问)。

不幸的是,在框架中通常没有对此编码的内置支持。另一方面,自己编写或在线查找代码相对简单。

http://en.wikipedia.org/wiki/Base32

答案 1 :(得分:10)

RFC 3548建议不仅要替换/字符。 URL和文件名安全字母替换:

  • 带有下划线/
  • 的63:_字符
  • 带有减号+的62:-字符。

但也许你最好使用HEX-String。有一段时间,我将哈希值存储在文件名中。我开始使用Base64 String,但切换到Hex-String。我不记得我为什么要切换,也许是因为Windows在'a'和'A'之间没有区别,正如AndiDog所说。

答案 2 :(得分:10)

我不确定您使用的编码是什么,但请考虑percent encoding文件名。

  • 适用于所有文件系统
  • 只要文件名在ASCII范围内
  • ,它就可以保存文件名

答案 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哈希的十六进制表示,因为这是将它们表示为字符串的相当标准的方式。