2017-02-14 10 views
0

私は現在、JavaのバックグラウンドでPHPを使い始めています。私は基本的な暗号化のためにmcryptを使用していますmcrypt_encrypt (string $cipher , string $key , string $data , string $mode [, string $iv ])暗号化はうまくいきますが、2つの文字列を連結して暗号化する必要がありますが、私はこれを行うと出力はまるでそれぞれの文字列を別々に暗号化して連結した暗号化の前ではなく、後で。PHP mcrypt - mcryptは、各文字列を連結された文字列にseperatlyで暗読します。

function base64url_encode($data) { 
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
} 

function base64url_decode($data) { 
    return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); 
} 

function encryptCode($data){ 
    return mcrypt_encrypt(MCRYPT_DES , '12345678' , $data , 'cbc' ,'87654321'); 
} 

function decryptCode($data){ 
    return mcrypt_decrypt(MCRYPT_DES , '12345678' , $data , 'cbc' ,'87654321'); 
} 

$id = 'Q2JmDpmqjNmGT4FJ2EkXXITOgc31ZA52'; 
$toAdd = 'hellothere'; 
$base64Decoded = base64url_decode($id); 
$decrypted = decryptCode($base64Decoded); 
$decrypted = $decrypted.$toAdd; 
$encryptedID = encryptCode($decrypted); 
$base64Encoded = base64url_encode($encryptedID); 
print_r($base64Encoded); 

と、出力は次のようになります:私は何をやっていることはこれですQ2JmDpmqjNmGT4FJ2EkXXITOgc31ZA52DG4cvxVuJVnkcrINN0Zt9g

私はDESの弱さを認識していますが、私は、この場合にはそのことについてそうしてくださいコメントを、それを必要としません。あなたの助けに感謝します。

+1

'myKey'と 'myIV'は受け入れられない値なので、投稿したコードはまったく動作しません。実際のコードを含めることで、実際にここで何をしているのかを知る必要があります。 – billynoah

+0

@billynoahはい私はそれらが容認できる値ではないことを認識していますが、どのキーまたはivが同じ出力を引き起こすので、実際の問題ではないので、実際の値ではなく、ivおよびkey問題は依然として続く –

+0

mcryptを使用しないことをお勧めします。これは10年近く前から放棄されました。このため、PHP 7.2では非推奨となり、コアからPECLに削除されます。標準のPKCS#7(néePKCS#5)パディングはサポートされていません。バイナリデータでも使用できない非標準のヌルパディングのみがサポートされています。 mcryptには、2003年の傑出したバグがたくさんあります。代わりに、[defuse](https://github.com/defuse/php-encryption)や[RNCryptor](https://github.com/RNCryptor)の使用を検討すると、完全な解決策は、維持されており、正しいです。 – zaph

答えて

0

mcrypt_encryptは、運転のCBCモードを尊重していない理由を私が言うことができない(実際の入力と出力を見ることなく、私はそれがECBとして演技と仮定しています)。おそらくmcryptさんのデフォルトのヌルパディングアルゴリズム(0x00)が問題を引き起こしていますか?私はmcryptが今〜10年間放棄されていると言うことができるので、それを理解しようとエネルギーを費やすことはありません。 libsodiumを使用するか、それ以外の場合は少なくともopensslを使用してください。

This post by Scott Arciszewskiは、PHPでmcryptの問題を説明しています。

更新

私は予想通りCBCモードが働いていたことを証明するためにあなたの提供されたコードとmade some additional modificationsを走りました。

function base64url_encode($data) { 
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); 
} 

function base64url_decode($data) { 
    return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); 
} 

function encryptCode($data){ 
    return mcrypt_encrypt(MCRYPT_DES , '12345678' , $data , 'cbc' ,'87654321'); 
} 

function decryptCode($data){ 
    return mcrypt_decrypt(MCRYPT_DES , '12345678' , $data , 'cbc' ,'87654321'); 
} 

$id = 'Q2JmDpmqjNmGT4FJ2EkXXITOgc31ZA52'; 
$base64Decoded = base64url_decode($id); 
$decrypted = decryptCode($base64Decoded); 
print_r($decrypted."\n"); 
print_r("\n\n"); 

# Make the new plaintext string 
$toAdd = 'hellothere'; 
$additionalCipherText = encryptCode($toAdd); 
$additionalEncoded = base64url_encode($additionalCipherText); 
print_r("Additional cipher text: ".$additionalEncoded."\n"); 
print_r("\n\n"); 

# Concatenate the plaintext and encrypt 
$plaintext = $decrypted.$toAdd; 
$cipherText = encryptCode($plaintext); 
$base64Encoded = base64url_encode($cipherText); 
print_r("  New cipher text: ".$base64Encoded."\n"); 
print_r("Original cipher text: ".$id.$additionalEncoded."\n"); 
print_r("\n\n"); 

# Try the reverse order 
$plaintext = $toAdd.$decrypted; 
$cipherText = encryptCode($plaintext); 
$base64Encoded = base64url_encode($cipherText); 
print_r("  New cipher text: ".$base64Encoded."\n"); 
print_r("Original cipher text: ".$additionalEncoded.$id."\n"); 

私は次の出力受信:

��t 
anEncryptedId 


Additional cipher text: paTJPP5mr-65c1OKybvB1A 


    New cipher text: Q2JmDpmqjNmGT4FJ2EkXXITOgc31ZA52DG4cvxVuJVnkcrINN0Zt9g 
Original cipher text: Q2JmDpmqjNmGT4FJ2EkXXITOgc31ZA52paTJPP5mr-65c1OKybvB1A 


    New cipher text: paTJPP5mr-69piYC2Ep0BM1tiph63ZFqdg_whovwRh0-4AD37H2JPQ 
Original cipher text: paTJPP5mr-65c1OKybvB1AQ2JmDpmqjNmGT4FJ2EkXXITOgc31ZA52 

あなたが見ることができるように、それ自体でちょうど$toAddを暗号化して提供する暗号文と連結ない同じ。ここで私が走ったコードです平文を連結して暗号化する。 Base64でエンコードされた出力の33番目の文字は、違いが始まる場所であることがわかります。Base64の33番目の文字は暗号テキストの25番目のバイトの始まりです。 DESでは、ブロックサイズは64 bits/8 bytesであるため、最初の3つのブロックは同じように暗号化されます。次のブロックは、前のブロックの暗号文の^操作によって変更され、そうでない場合はIVが使用されます。

私は2つの平文入力の逆の順序でこの操作を繰り返しました。ここでも、Base64出力の最初の12文字(12文字 - > 8バイト)が同じで、違いがあることがわかりました。これは、元の平文が完全なブロック境界で終了しないため、新しい「第2のブロック」は元の「第2のブロック」と同一ではないため、予想されます。 CBCの操作はここで正常に動作し、2番目のブロックを「ジャンパー」します。

私はこのデータの取り扱いに関するコードを再度確認し、あなたが思っている操作(および順序)を実行していることを確認します。

+0

すべての表示は、すべての失敗に対して、 'mcrypt'がCBCモードを正しく正しく実行することを示しています。私の賭けは、パディングを伝えないヌルパディングと連結です。答えはもっとコメントです。 – zaph

+0

なぜ、 '$ id'は単独で、または連結テキストで暗号化されても同じですか?これは私が理解していない部分、私はjavaで同じ手順をやっていると出力が異なる理由はなぜですか?暗号化されたデータは、phpやjavaで操作する必要がありますが、phpはdiffetentな何かをしているようです。通常は '$ id'に何かを追加すると、出力だけでなく出力全体が変更されます。 –

+0

@Amroelaswar選択された変数名は恐ろしく、コードを難しくします。 '$ base64Decoded'、' $ decrypted'、 '$ base64Encoded'のような名前は、何が何であるか疑問に思う読者を残します。適切なネーミングは、まともな理解可能なコードを作成するための第一歩です。 – zaph

関連する問題