Java Base64 编码对文件名安全吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3945541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 07:21:08  来源:igfitidea点击:

Base64 Encoding safe for filenames?

javahashencodingbase64filenames

提问by cweston

Is Base64 encoding safe to use for filenames on Windows and Linux systems? From my research I have found that replacing all /characters of the result with -or _should resolve any issues.

将 Base64 编码用于 Windows 和 Linux 系统上的文件名是否安全?根据我的研究,我发现/将结果的所有字符替换为-or_应该可以解决任何问题。

Can anyone provide more details on this?

任何人都可以提供更多详细信息吗?

Currently in Java I am using the following peice of code:

目前在 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('/','_');

采纳答案by Alexei Levenkov

Modified Base64 (when /,=and +are replaced) is safe to create names but does not guarantee reverse transformation due to case insensitivity of many file systems and urls.

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

Base64 is case sensitive, so it will not guarantee 1-to-1 mapping in cases of case insensitive file systems (all Windows files systems, ignoring POSIX subsystem cases). Most urls also case insensitive preventing 1-to-1 mapping.

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

I would use Base32 in this case - you'll get names a bit longer, but Base32 encoded values are 100% safe for file/uri usage without replacing any characters and guarantees 1-to-1 mapping even in cases of insensitive environment (FAT/Win32 NTFS access).

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

Unfortunately there is usually no built-in support for this encoding in frameworks. On other hand code is relatively simple to write yourself or find online.

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

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

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

回答by AndiDog

Usually MD5 hashes (hashes in general) are represented as hexadecimal strings instead of Base64, which then only contain [a-f0-9]. Those names would be supported by all filesystems.

通常 MD5 散列(通常是散列)表示为十六进制字符串而不是 Base64,然后只包含 [a-f0-9]。所有文件系统都支持这些名称。

If you really want to use Base64, your solution (replacing slashes) will not work correctly as Windows filesystems don't make a difference between 'A' and 'a'. Maybe you want to use Base32 instead? But mind that Base32 makes 8 bits out of 4, so it will be easier to just take the hexadecimal representation.

如果您真的想使用 Base64,您的解决方案(替换斜线)将无法正常工作,因为 Windows 文件系统在“A”和“a”之间没有区别。也许您想改用 Base32?但请注意,Base32 在 4 中生成 8 位,因此仅采用十六进制表示会更容易。

In general, the following characters are not allowed in Windows and/or Linux: \ / : * ? " < > |

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

回答by Michael Madsen

A filename created by Base64 is only safe if you use a different character from /, which you do, as NTFS does not allow that character to be used in file names. As long as you do that, pretty much all commonly used file systemsin common use will be OK.

仅当您使用与 / 不同的字符时,Base64 创建的文件名才是安全的,因为 NTFS 不允许在文件名中使用该字符。只要你这样做,几乎所有常用的常用文件系统都可以。

However, if the filesystem is case-insensitive, as is the case on Windows, you can get collisions because the Base64 alphabet contains both upper and lower-case.

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

You might want to consider using the hexadecimal representation of your MD5 hash instead, since this is a fairly standard way of representing those as a string.

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

回答by Christian Ammer

RFC 3548suggests not only to replace the /character. The URL and Filename safeAlphabet replaces:

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

  • the 63:nd /character with the underscore _
  • the 62:nd +character with the minus -.
  • 63:nd/带下划线的字符_
  • 62:nd+带有减号的字符-

But maybe you better use a HEX-String. It is been a while, when i stored a hash value in a filename. I started with using Base64 String but switched to a Hex-String. I don't remember why i switched, maybe because Windows makes no difference between 'a' and 'A' as AndiDog said.

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

回答by Pekka

I'm not sure what you are using the encoding for, but consider percent encodingfile names.

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

  • It works in every file system
  • It keeps file names human readable as long as they're within the ASCII range
  • 它适用于每个文件系统
  • 只要文件名在 ASCII 范围内,它就可以保持文件名的可读性

回答by sigs

One-liner for C#:

C# 的单行:

String filename = Convert.ToBase64String(new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes("UTF-8 string with snowmen"))).Replace("+", "_").Replace("/", "-").Replace("=","");

Needs the following to the beginning of the file:

需要以下内容到文件的开头:

using System.Security.Cryptography
using System.Text