2010-10-15 182 views
22

Base64編碼是否可安全地用於Windows和Linux系統上的文件名?從我的研究中,我發現用-_替換所有/字符的結果應解決任何問題。Base64編碼對文件名安全嗎?

任何人都可以提供這方面的更多細節?

在Java中

目前我使用下面的代碼peice的:

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('/','_'); 
+1

'/'似乎是一個有效的base64字符(否)。 63)但我從未在真實世界中看到它:http://en.wikipedia.org/wiki/Base64 – 2010-10-15 19:48:01

+10

請注意,Windows文件系統不區分大小寫。你不能指望一個獨特的哈希映射到一個獨特的文件。 – laalto 2010-10-15 19:51:22

回答

25

修改的Base64(當/=+被替換)安全地創建名字,但不保證逆變換由於許多文件系統和URL不區分大小寫。

Base64是大小寫敏感的,所以它不會保證不區分大小寫的文件系統的情況下,1對1的映射(所有Windows文件系統,而忽略POSIX子系統的情況下)。大多數網址也不區分大小寫,防止1對1映射。

我會在這種情況下使用Base32 - 你會得到更長的名稱,但Base32編碼值對於文件/ uri的使用是100%安全的,無需替換任何字符,並保證1對1映射,即使在不敏感的環境(FAT/Win32 NTFS訪問)。

不幸的是,在框架中通常沒有內置的對這種編碼的支持。另一方面,編寫代碼相對簡單,你可以自己寫或在網上找到。

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

+0

你可以在php中使用base_encode函數,參見http://stackoverflow.com/questions/1848601/does-php-have-a-built-in-coversion-to-base32-values – Mark 2010-11-15 21:48:57

+1

@Mark base_encode只適用於值可以用PHP中的數字表示,確切的精確度取決於平臺,但超過14個十進制數字(大約9個base32數字)的任何內容都不能保留整數精度,因此不適合使用字符串/散列。 – thomasrutter 2013-03-24 00:27:34

+0

Guava現在支持[Base32編碼](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io/BaseEncoding.html#base32())。 – 2014-09-26 13:25:28

1

一般MD5散列(通常散列)被表示爲十六進制字符串代替Base64編碼,然後只包含[A-f0-9 ]。這些名稱將被所有文件系統支持。

如果您真的想使用Base64,您的解決方案(替換斜槓)將無法正常工作,因爲Windows文件系統不會在「A」和「a」之間產生區別。也許你想用Base32來代替?但是請注意,Base32會使用4位中的8位,因此僅採用十六進制表示就會更容易。

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

2

由Base64創建的文件名只有在使用/中的不同字符時纔是安全的,因爲NTFS不允許在文件名中使用該字符,只要這樣做,很常用的多all commonly used file systems將確定。

然而,如果文件系統是不區分大小寫,因爲是在Windows的情況下,你可以得到碰撞,因爲Base64編碼字母包括大寫和小寫。

您可能需要考慮使用MD5散列的十六進制表示法,因爲這是一種相當標準的代表方式憎恨那些作爲一個字符串。

9

RFC 3548建議不僅要替換/字符。該URL和文件名安全字母代替:

  • 63:第二/字符以下劃線_
  • 62:ND與負-+字符。

但也許你最好使用HEX字符串。這是一段時間,當我存儲一個散列值的文件名。我開始使用Base64字符串,但切換到一個十六進制字符串。我不記得爲什麼我換了,也許是因爲Windows在'a'和'A'之間沒有區別,正如AndiDog所說。

+0

[RFC 4648](http://tools.ietf.org/html/rfc4648#page-7)仍然表示相同... – 2013-08-31 20:23:00

10

我不確定你使用的編碼是什麼,但考慮percent encoding文件名。

  • 它可以在每個文件系統
  • 它使人類可讀的文件名,只要它們是ASCII範圍
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 
+2

這並不解決不區分大小寫的問題。 – Dan 2014-12-29 19:20:24