3

PHP で次の DES 暗号化スキームを作成しました。静的な初期化ベクトルを使用して、出力と入力が 1 対 1 でマッピングされるようにします。

PHP コード:

function encrypt($plaintext, $key)
{
    # use an explicit encoding for the plain text
    $plaintext_utf8 = utf8_encode($plaintext);

    # create a random IV to use with CBC encoding
    # $iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_CBC);
    # $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    # defining a constant IV to use with CBC encoding
    $iv = "kritanj ";

    # creates the DES cipher text 
    $ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $plaintext_utf8, MCRYPT_MODE_CBC, $iv);
    # prepend the IV for it to be available for decryption
    $ciphertext = $iv . $ciphertext;   

    # encode the resulting cipher text so it can be represented by a string
    $ciphertext_base64 = base64_encode($ciphertext); 

    return $ciphertext_base64;
}

function decrypt($ciphertext_base64, $key)
{   
    $ciphertext_dec = base64_decode($ciphertext_base64);

    # retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
    # $iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_CBC);
    # $iv = substr($ciphertext_dec, 0, $iv_size);
    $iv = "kritanj ";

    # retrieves the cipher text (everything except the $iv_size in the front)
    $ciphertext_dec = substr($ciphertext_dec, $iv_size);

    # decrypting the DES cipher text 
    $plaintext_utf8_dec = mcrypt_decrypt(MCRYPT_DES, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv);
    return $plaintext_utf8_dec;
}

$plaintext = "The secret message is : " ;
$key = "7chrkey" ;
$ciphertext = encrypt($plaintext, $key);
echo "Encrypted: ".$ciphertext ."<br>";
$plaintext1 = decrypt($ciphertext, $key);
echo "Decrypted: ".$plaintext1  ;

出力:

Encrypted: a3JpdGFuaiB3DY63WHnE9led43FyFe53HlhUEr+vVJg=
Decrypted: The secret message is :

今、私はpythonで同等のコードを書こうとしましたこれが私が管理したものです

Python コード:

import binascii
def conv_sevnCharKey_to_64bit_DESkey(key):
  st = bin(int(binascii.hexlify(key), 16))
  st = st[2:]
  des_key = ''
  for i in xrange(8) :
    parity = 0
    sevnBits = st[i*7:i*7+7]
    for c in sevnBits :
      if c in '1' :
        parity += 1
    if parity % 2 == 0 :
      eigthBytes = sevnBits + '1'
    else :
      eigthBytes = sevnBits + '0'
  des_key += eigthBytes

  n = int('0b'+des_key, 2)
  DESkey =  binascii.unhexlify('%x' % n)

  return DESkey

from pyDes import *
plaintext = "The secret message is : "
iv = 'kritanj '
key = conv_sevnCharKey_to_64bit_DESkey('7chrkey')

plaintext_utf8 = plaintext.encode('utf-8')
# iniltalizing DES in cbc mode     
k = des(key, CBC, iv)
# encrypting
ciphertext = k.encrypt(plaintext_utf8)
# prepending the IV
ciphertext = iv + ciphertext;
# encoding to base64 
ciphertext_base64 = ciphertext.encode('base64','strict')

print "Encrypted: ", ciphertext_base64

# decoding base64 
ciphertext= ciphertext_base64.decode('base64','strict')
# striping the IV and decrypting
plaintext_utf8 = k.decrypt(ciphertext[8:])
# decoding utf-8 (if nessacary)
plaintext1 = plaint`ext_utf8.decode('utf-8') 

print "Decrypted: ", plaintext1

assert plaintext1== plaintext

出力:

Encrypted:  a3JpdGFuaiD+sGHb2GfZSXDac1r6mH+JDx7535yxL9k=

Decrypted:  The secret message is : 

暗号文が異なるのはなぜですか?そして、それらが同一であることを確認する方法はありますか?

[上記の php コードを使用して、二重 DES 暗号化で暗号化されたテキストに対して「中間攻撃」攻撃を行いたいです。しかし、暗号化を再作成できないため、攻撃を実装できません]

4

1 に答える 1

2

キーをパディングするスキームが PHP コードと異なるようです。

from pyDes import *
plaintext = "The secret message is : "
iv = 'kritanj '
key = '7chrkey'
plaintext = plaintext.encode("utf-8")
iv = 'kritanj '
k = des(key+'\0', CBC, iv)
print (iv + k.encrypt(plaintext)).encode("base64", "strict")

出力:

'a3JpdGFuaiB3DY63WHnE9led43FyFe53HlhUEr+vVJg=\n'

つまり、暗号化キーに NULL バイトを埋め込むと、PHP コードと同じ結果が得られます。

于 2013-04-26T12:19:52.607 に答える