2015-01-13 21 views
3

我需要在一對PHP腳本中進行對稱加密和解密。我正在使用mcrypt_encrypt和crypt_decrypt。爲了驗證這一點,我有以下代碼:來自mcrypt_decrypt的額外字符輸出

$encrypted_token = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $ENCRYPTION_SECRET, $refresh_token, MCRYPT_MODE_ECB); 

$encrypted_encoded_token=base64_encode($encrypted_token); 
echo "\nEncrypted Token: " . $encrypted_encoded_token . "\n"; 

要進行測試,在相同的PHP腳本我執行以下操作:

$decoded_refresh_token = base64_decode($encrypted_encoded_token); 

$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $ENCRYPTION_SECRET, $decoded_refresh_token, MCRYPT_MODE_ECB); 
echo "\nDecrypted Token After decrypt: " . $decrypted . "\n"; 

我輸入$ refresh_token是字符的長字符串,看起來像這樣(只長):

AQCNKTZhaWTmUl3WvHOtlkv2Vc-Ybkl24D5Zp1lZPLBraTxrr-YQhErXrI2IWWEIWk5lnBc1k 

解密的令牌看起來像這樣解密後:

AQCNKTZhaWTmUl3WvHOtlkv2Vc-Ybkl24D5Zp1lZPLBraTxrr-YQhErXrI2IWWEIWk5lnBc1k������������������� 

我的$ ENCRYPTION_SECRET長度是32個字符。 base64_encode和解碼是因爲我是json_encoding並在Post中解碼令牌。

我在做什麼錯?

+0

你看過那些額外的字符是什麼?例如如果它們是空值,那麼它們可能是通過加密添加的填充字符,以使字符串達到crypt算法要求的任何塊大小。 –

+0

@MarcB對不起,我怎麼知道這些角色是什麼? – JeffB6688

+0

使用'ord(substr($ decrypted,32,1))'或任何偏移量。看看char的值是什麼。 –

回答

8

那些額外的字符確實是字節值爲零。 PHP的mcrypt使用0..n - 1字節的零填充,其中n是塊大小。換句話說,如果明文已經是塊大小的倍數,那麼它不會填充。否則,它會填充到塊大小。

現在您正在使用MCRYPT_RIJNDAEL_256這不是AES,而是Rijndael,塊大小爲256位。所以添加的字節數是0..31個字節。如果您將它們視爲字符串,則它們會轉換爲問號或刪除,具體取決於您查看字符串的方式。在mcrypt的C庫中,可能更有意義,因爲零會終止以null結尾的字符串。

當前的特別標準是PKCS#7填充,它增加了填充字節的1..blocksize。如果x是填充字節數,則x也是所添加字節的值。 PKCS#7填充是確定性的,即無論明文的值如何,您都可以不加鍵入。零填充的行爲大致相同,除非明文在末尾包含零個字符。然而,對於可打印字符串(ASCII,拉丁或UTF-8)而言,情況並非如此。

最後,要刪除填充,只需執行rtrim(plaintext, "\0"),您將獲得原始字符串。