2015-09-22 2 views
1

Я новичок в PHP и моем первом задании. Секретное слово зашифровывается с использованием C# (TripleDES/Кодировка ключа ASCII в PHP

CBC). При сравнении я обнаружил, что IV и байты секретного слова соответствуют, но не ключу.

Это C# код, который работает отлично ...

string epws = secretWord; 
    byte[] rawdata = Convert.FromBase64CharArray(char[] aArr); 
    mCryptoService = new TripleDESCryptoServiceProvider(); 

    string key = ASCIIEncoding.ASCII.GetString(rawdata); 
    key = key.Substring(0, 24); 
    mCryptoService.Key = ASCIIEncoding.ASCII.GetBytes(key); 

    byte[] ivB = new byte[8]; 
    Buffer.BlockCopy(rawdata, 31, ivB, 0, 8); 
    mCryptoService.IV = ivB; 

    byte[] epwb = Convert.FromBase64String(epws); 
    ICryptoTransform cryptoTransform = mCryptoService.CreateDecryptor(); 
    MemoryStream ms = new MemoryStream(epwb, 0, epwb.Length); 
    CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read); 
    StreamReader sr = new StreamReader(cs); 
    return sr.ReadToEnd(); 

Это PHP код, который мне нужна помощь ...

<?php 

// dkey is the rawdata passed in as string from database 

$byteArray = unpack('C*', $dkey); 
$mkey = implode(array_map('chr', $byteArray)); 
$mkey = base64_decode($mkey); 

$iv = substr($mkey, 31, 8); 
$mkey = substr($mkey, 0, 24); 

// the encrypted secretword passed in as string from database 
$epws = base64_decode($epws); 

$ok= trim(mcrypt_decrypt(MCRYPT_3DES, $mkey, $epws, MCRYPT_MODE_CBC, $iv)); 

?> 

Это ключи, которые отличаются. ЕСЛИ я заменю ключ C# в php, он отлично работает.

From c# 
key = (35, 63, 63,43, 63,49,20, 63, 63,97,21,24, 63,97, 63, 63,125,98,125,15,62,108,55,70) 

From php    
key = (35,229,239,43,244,49,20,141,144,97,21,24,200,97,196,216,125,98,125,15,62,108,55,70) 
     ^^ ^  ^^  ^ ^^

Не знаю, что еще делать.

+0

Когда я вижу '$ ok = trim (mcrypt_decrypt (MCRYPT_3DES, $ mkey, $ epw, MCRYPT_MODE_CBC, $ iv));' Интересно, неверна ли '$ epw', должна ли она быть' $ epws'? – Twisty

+0

Ваши права. Я внес изменения. Благодарю. – prav

ответ

1

Ключ состоит из байтов, а не символов. Если вам нужна клавиша, отображаемая в виде строки - обычно вы этого не делаете - тогда вы должны закодировать ее на шестнадцатеричные. Если вы хотите использовать его позже, вы можете снова декодировать шестнадцатеричные массивы в байтовый массив.

ASCII имеет значения от 0 до 127, из которых нижние 32 символа, а также значение 127 не могут быть распечатаны. Таким образом, ваш код на C# в этом смысле хуже, чем ваш PHP-код, и ему нужно самое большое изменение.


В настоящее время # коды C просто заменить байты за пределами диапазона ASCII (0-127) с вопросительными знаками (3F гекса, или 63 в десятичных знаках - проверьте распечатку ключа). Вы можете просто заменить каждое значение 128 или выше, со значением 63.

Очевидно, что это означает, что ваш ключ теряет энтропию, в среднем это будет только половина сильным (правда, в вашем примере, с 8 байт заменить) , Если вам не повезло, то все байтов преобразуются в вопросительные знаки (примерно один раз в 65536) или что-то среднее между ними, что делает вас чрезвычайно уязвимыми для атаки.

+0

У меня не так много говорят о коде C#. Мое внимание сосредоточено на стороне PHP, чтобы работать. Благодарю. – prav

+1

@prav Вы не должны просто следовать какой-либо спецификации без комментариев, прав. Человек, дающий задание, должен сначала понять, что такое криптография, прежде чем пытаться учить других. Измененный ответ в любом случае. –

+0

Вы правы. Я проверил распечатку с ключа, и, как вы сказали, у него были вопросительные знаки. Поэтому единственное, что я могу сделать в PHP-коде, - это заменить значение. Кроме того, спасибо за ваш совет. – prav

Смежные вопросы