2017-09-21 3 views
2

私は以下の通りであるPHPファイルがあります。変換PHPでopensslのAES

$encryption_encoded_key = 'c7e1wJFz+PBwQix80D1MbIwwOmOceZOzFGoidzDkF5g='; 

function my_encrypt($data, $key) { 
    $encryption_key = base64_decode($key); 
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cfb')); 

    $encrypted = openssl_encrypt($data, 'aes-256-cfb', $encryption_key, 1, $iv); 

    // The $iv is just as important as the key for decrypting, so save it with encrypted data using a unique separator (::) 
    return base64_encode($encrypted . '::' . $iv); 
} 

function my_decrypt($data, $key) { 
    // Remove the base64 encoding from key 
    $encryption_key = base64_decode($key); 

    // To decrypt, split the encrypted data from IV - unique separator used was "::" 
    list($encrypted_data, $iv) = explode('::', base64_decode($data), 2); 

    return openssl_decrypt($encrypted_data, 'aes-256-cfb', $encryption_key, 1, $iv); 
} 

$data = 'USER_ID||NAME||EMAIL||MOBILE'; 
$data_encrypted = my_encrypt($data, $encryption_encoded_key); 
echo $data_encrypted; 
$data_decrypted = my_decrypt($data_encrypted, $encryption_encoded_key); 
echo "Decrypted string: ". $data_decrypted; 

これは正常に動作、および暗号化キーで暗号化/復号化することが可能であるが、今私はまたのpythonを持っていますファイル:

import hashlib 
import base64 
from Crypto.Cipher import AES 
from Crypto import Random 

encryption_encoded_key = 'c7e1wJFz+PBwQix80D1MbIwwOmOceZOzFGoidzDkF5g=' 

def my_encrypt(data, key): 
    #Remove the base64 encoding from key 
    encryption_key = base64.b64decode(key) 
    #Generate an initialization vector 
    bs = AES.block_size 
    iv = Random.new().read(bs) 

    cipher = AES.new(encryption_key, AES.MODE_CFB, iv) 
    #Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector. 
    encrypted = cipher.encrypt(data) 

    #The iv is just as important as the key for decrypting, so save it with encrypted data using a unique separator (::) 
    return base64.b64encode(encrypted + '::' + iv) 


def my_decrypt(data, key): 
    #Remove the base64 encoding from key 
    encryption_key = base64.b64decode(key) 

    #To decrypt, split the encrypted data from IV - unique separator used was "::" 
    encrypted_data, iv = base64.b64decode(data).split('::') 

    cipher = AES.new(encryption_key, AES.MODE_CFB, iv) 

    return cipher.decrypt(encrypted_data) 

data = 'USER_ID||NAME||EMAIL||MOBILE' 

print "Actual string: %s" %(data) 
data_encrypted = my_encrypt(data, encryption_encoded_key) 
print data_encrypted 

data_decrypted = my_decrypt(data_encrypted, encryption_encoded_key) 
print "Decrypted string: %s" %(data_decrypted) 

また、これは正常に動作します私のpythonからこれを使用しようとすると、入力された文字列を暗号化/復号化することができ、 私はPHPファイルを使用して暗号化し、Pythonで出力を復号化したい、両方が使用する必要がありますAES 256 CFBモードを使用した暗号化、何が間違っていますか?

+1

プロセスがある場合ブレアキングダウン?各メソッドの暗号化/復号化操作を実行する前に、解析されたキー、iv、データなどを印刷できますか?それは少なくともあなたに出発点を与えるでしょう – Kritner

+0

ああ、ひとつ注意すべき点は、PythonやPHPについて多くのことを知らず、参照型を探すことです。 「iv」は、暗号化/復号化操作を実行中に、各ブロックを介して潜在的に変更される。あなたが(単純な例として) '... 0001'のivで始まる場合、最初のブロックの後に、そのivは' ... 0002'として表されるかもしれません。 (潜在的に)修正されたものではなく、両方の実装で「元の」ivを追加していることを確認してください。 – Kritner

答えて

2

CFB modeを使用するには、セグメントサイズを指定する必要があります。 OpenSSLはaes-256-cfb(128ビット)、aes-256-cfb1(1ビット)、aes-256-cfb8(8ビット)(およびAES-128と192の同様のモード)を持っています。だから、あなたのPHPコードで128ビットのcfbを使用している。

ザ・PythonライブラリはAES.newからsegment_sizeの引数を受け入れますが、デフォルトではあるので、あなたは、2つのバージョンの異なるモードを使用しています。

暗号オブジェクト128のセグメントサイズを追加し、PHPコードの出力を復号化するPythonコードを取得する:

cipher = AES.new(encryption_key, AES.MODE_CFB, iv, segment_size=128) 

(NBこれはPyCryptoの新しいPyCryptodome forkを使用しているPyCryptoは、A有します。バグここには動作しません)

また、あなたが暗号を設定することにより、CFB-8を使用するためにPHPコードを取得することができます(もちろん、両方を変更しないでください):。

$encrypted = openssl_encrypt($data, 'aes-256-cfb8', $encryption_key, 1, $iv); 
+0

これで完璧に動作します。これにアプローチする方法はありますか?暗号化の種類を推測しようとするのではなく、同じことを行うことができるPythonのopensslラッパーがありますか?私の暗号化/復号化メソッドを書き直すことはできないように、aesからcast5-cbcに暗号を変更します。 –

+0

素敵な答えですが、私はこの問題がsegment_sizeと何か関係がありますが、どのように変更するか考えていないと感じています... – georgexsh

関連する問題