Java Base64编码文件名是否安全?

Java Base64编码文件名是否安全?,java,hash,encoding,base64,filenames,Java,Hash,Encoding,Base64,Filenames,在Windows和Linux系统上,文件名使用Base64编码安全吗?根据我的研究,我发现用-或-替换结果中的所有/字符可以解决任何问题 有人能提供更多的细节吗 目前在Java中,我正在使用以下代码: MessageDigest md5Digest = MessageDigest.getInstance("MD5"); md5Digest.reset(); md5Digest.update(plainText.getBytes()); byte[] digest = md5Digest.dig

在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('/','_');
通常MD5散列(通常是散列)表示为十六进制字符串,而不是Base64,后者只包含[a-f0-9]。所有文件系统都支持这些名称

如果您真的想使用Base64,您的解决方案(替换斜杠)将无法正常工作,因为Windows文件系统无法区分“a”和“a”。也许你想改用Base32?但是请注意,Base32将4中的8位转换为8位,因此只采用十六进制表示形式会更容易


通常,Windows和/或Linux中不允许使用以下字符:\/:*?“<>|

由Base64创建的文件名只有在您使用与/不同的字符时才是安全的,因为NTFS不允许在文件名中使用该字符。只要您这样做,基本上通用就可以了

但是,如果文件系统不区分大小写,就像在Windows上一样,则可能会发生冲突,因为Base64字母表同时包含大小写

您可能想考虑使用MD5哈希的十六进制表示,因为这是表示字符串的一种相当标准的方式。

< P>修改的Base64(当代码>/< /COD>,<代码>=和<代码> +>代码>被替换)创建名称是安全的,但由于许多文件系统和URL不区分大小写,因此不能保证反向转换

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

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

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

.

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

  • 带下划线的63:nd
    /
    字符
  • 带负号的62:nd
    +
    字符
    -

<>但是也许你最好使用一个十六进制字符串。当我在文件名中存储一个哈希值的时候已经有一段时间了。我开始使用Base64字符串,但是切换到一个十六进制字符串。我不记得我为什么切换了,可能是因为Windows没有像AndiDog所说的那样在“A”和“A”之间没有区别。

< P>我不确定你用的是什么编码,但是考虑一下。文件名

  • 它适用于所有文件系统
  • 只要文件名在ASCII范围内,它就可以让人可读
一个C#衬里:

需要在文件开头添加以下内容:

using System.Security.Cryptography
using System.Text

/
似乎是有效的base64字符(第63号)但我从未在现实世界中见过它:请注意,Windows文件系统不区分大小写。您不能指望一个唯一的哈希映射到一个唯一的文件。您可以在php中使用base_encode函数,请参阅@Mark base_encode仅适用于可以在php中表示为数字的值,确切的精度取决于平台,但无论如何g超过14位十进制数字(大约9位base32位)可能无法保留整数精度,因此不适合字符串/哈希。Guava现在支持。修改后的Base64(当/、=和+被替换时)创建名称是安全的,但由于许多文件系统和URL不区分大小写,因此不能保证反向转换。您能详细解释一下吗?@gstackoverflow Base64区分大小写,因此如果您想反向转换回字节,则必须保留大小写(“Baaa”->“05 A6 9A”,但“Baaa”=>“04 00”)在FAT/FAT32上,文件名被规范化为大写-因此您无法将从文件系统读取的文件名转换回字节数组。同样,URL的参数也经常被规范化(通常是由于误解,但仍然如此),从而导致相同的问题。此外,一些文件系统(NTFS)区分大小写,但不允许名称仅按大小写变化-因此您不能从不同的字节构造“唯一”NTFS名称。这并不能解决大小写不敏感的问题。我不会称此为一行。读取代码时需要水平滚动实际上,Linux(和许多UNIX衍生产品)中唯一禁止的字符在其本机文件系统上是
/
NUL
。通常没有必要(而且容易混淆)偏离更严格的Windows设置。下面是一个示例(并假设程序按照目标限制正确编写;然后,即使Windows资源管理器多年来都未能通过对有效FAT32和NTFS文件名的测试)。
using System.Security.Cryptography
using System.Text