簡體   English   中英

PHP中的加密安全隨機ASCII字符串

[英]Cryptographically secure random ASCII-string in PHP

我知道PHP 7中的random_bytes() ,我想用它來生成加密安全(例如,難以猜測)的隨機字符串,以用作一次性令牌或在cookie中長期存儲。

不幸的是,我不知道如何將random_bytes()的輸出轉換為僅包含人類可讀字符的字符串,因此瀏覽器不會感到困惑。 我知道bin2hex() ,但是我更喜歡使用完整的ASCII范圍而不是十六進制數字,以便每個長度有更多的位。

有任何想法嗎?

不幸的是,Peter O.在評論隊列中受到負面關注后刪除了他的答案,可能是因為他將其表述為問題。 我相信這是合理的答案,所以我會再次提出。

一種簡單的解決方案是使用base64_encode()將隨機數據編碼為base64字母。 這不會產生您所要求的“完整ASCII范圍”,但會為您提供大部分信息。 合適的base85編碼器可以輸出更大的ASCII范圍,但是php沒有內置的。 不過,您可能會發現很多用於php的開源base85編碼器。 在我看來,base85的長度比base64的減少不太值得您必須維護的額外代碼。

我個人只是使​​用一個GUID庫,並連接了幾個GUID,以獲得一個長的唯一令牌字符串。 您還可以選擇刪除破折號,以使其難以了解來源,並且如果要使其更加復雜,則可以將字符串隨機最多減少10個字符,以增加其未知長度的復雜性。

我使用此庫來生成我的GUID

https://packagist.org/packages/ramsey/uuid

use Ramsey\Uuid\Uuid;
$token = Uuid::uuid4() . '-' . Uuid::uuid4();

抱歉,我忽略了您想要使用數字范圍的26個alpha字符的全部內容……不確定在這方面我是否為您提供答案,但是您應該對猜測UUID4的難度有信心,尤其是當您將一對加在一起,並將長度混淆10倍,使猜測變得更加復雜。

實際上,如果可以安全地生成有效ascii字符代碼范圍內的隨機數數組,則可以將整個隨機代碼數組轉換為相應的ascii字符並將它們作為單個字符串合並在一起。

function randomAsciiString($length) {
    return implode('', array_map(
        function($value) {
            return chr($value);
        },
        array_map(
            function($value) {
                return random_int(33, 126);
            },
            array_fill(0, $length - 1, null)
        )
    ));
}
echo randomAsciiString(128);                  // Normal 128 char string
echo randomAsciiString(random_int(118, 128)); // obfuscated length char string for extra complexity.

當然,不過...您應該注意,您正在使用鍵盤上的所有標准鍵,並且其中某些字符會破壞敏感內容(例如引號等)。

讓我們考慮要使用的字母。 為了簡單起見,我假設您只打算使用大小寫的英文字母。 這意味着您有26個大字母和26個小字母,以及52個不同的可能值。 如果我們將n個元素的字節數組視為以256為基數的n位數字,然后將此數字轉換為以52為基數的數字,其中A為0,B為1,C為2,...,a為26, ...,z為51,然后將這些數字轉換為相應的字母將得到所需的文本。

暫無
暫無

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

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