簡體   English   中英

嚴格檢查Base64解碼

[英]Robust Check Against Base64 Decode

快速說明:

我願意檢查要傳遞給Buffer.from的字符串是否為base64格式。 我了解到,檢查字符串是否為base64格式的最佳方法是通過regex,盡管它並不完美。 因此,我考慮過檢查base64解碼的結果,而不是檢查傳遞給base64解碼的內容。

編碼:

let buffer = Buffer.from('hey there', 'base64');
let bufferResult = buffer.toString('utf-8');
console.log(text.toString()) // Output: �쭅��

我正在嘗試做的是:

我想檢查和buffer.toString()的類似輸出,以保護我的應用程序免受不良輸出的影響。 我創建了簡單的RegEx來解決/^[a-zA-Z]+$/但我認為這不是很可靠(主要是因為我不知道是哪個buffer.toString()可以輸出)。

我是不是樹錯了樹,應該檢查Buffer.from的輸入,還是有正確的方法來實現我要執行的操作?

您的問題中有一個問題:Base64有多種編碼,具體取決於字符串中使用的其他非字母數字字符。

Base64編碼使用所有大寫ASCII字符,所有小寫字母,數字(這使26 + 26 + 10 = 62個字符)和另外兩個字符集(取決於您使用base64編碼的方式)的集合{'+', '/'} {'.', '-'} {'.', '_'}和其他一些(見這里進行徹底的解釋 )。

另一個問題是,通常,在較長的Base64字符串上,行長度限制為76個字符,因此base64字符串之間穿插了換行符(有些帶有/不帶CRLF對的\\r ),直到最后一行可以有一個,或者兩個'='字符。

另外,根據使用的字符總數( mod 4 ),一些(不是全部)base64字符串以一個或兩個'='字符結尾(這不是可選的,但是某些編碼(例如url)使用最后的等號)

如果您假裝解析+/ (用於mime編碼),則base64的有效(嚴格)正則表達式可以是

(((\r?\n|\s)*[A-Za-z0-9+\/]){4})*(((\r?\n|\s)*[A-Za-z0-9+\/]){2}((\r?\n|\s)*=){2}|((\r?\n|\s)*[A-Za-z0-9+\/]){3}((\r?\n|\s)*=){1})?

但在使用它之前要三思,因為它會匹配可能的最長base64字符串(因為它無法分析要匹配的上下文),並忽略其后的任何多余字符,因此對於無效的base64字符串,例如:

ABCDE

(具有5個字符,而base64必須是四個字符的倍數,包括最后的'=' ),它將與前四個字符( "ABCD"作為有效的base64匹配,因為這是可能匹配的最長的base64字符串)字符串有效,它應該已經編碼為ABCDEA== ,(假設最后一個字節的丟失的兩位為零)。請參見上面的演示,以獲取此示例。此外,空字符串也被匹配(它是有效的零長度base64字符串)

注意

好的base64解碼器不僅會以與regex匹配器相同的方式解析字符串,而且還會生成表示在其上的二進制字符串(花費的精力很少),因此我建議您不要使用 (在這種情況下) regex匹配器,但僅是一種練習, 或者也許是作為客戶端瀏覽器中的javascript驗證器使用 ,以在將base64編碼的字符串發送到服務器之前檢查格式,這還需要再次對其進行解碼)

筆記2

下一步是檢查base64字符串的好方法:強制在行的開頭和base64編碼的字符串之間以及從編碼的字符串的末尾和行的結尾之間僅允許空格(使base64編碼為被迫使用自己的行)這將使其成為更強大的測試:

^(((\r?\n|\s)*[A-Za-z0-9+\/]){4})*(((\r?\n|\s)*[A-Za-z0-9+\/]){2}(=(\r?\n|\s)*){2}|((\r?\n|\s)*[A-Za-z0-9+\/]){3}(=(\r?\n|\s)*))?$

在此處查看演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM