2012-05-03 5 views
2

У меня есть класс как на PHP, так и на C++, чтобы просто взять строку значений и сольную строку, чтобы сделать соление для конфиденциальности. Идея PHP-скрипта будет шифровать строку для C++-программы для приема и расшифровки. Они используют предварительно разделенную сольную строку, синхронный режим.Тот же код соления солей, дающий разные результаты

Проблема заключается в том, что похоже на ту же логику, что они генерируют другой результат для шифрования одной и той же строки. Это означает, что дешифрование строки или конца не приведет к исходной строке, которую она дала.

Возможно, что-то действительно просто я пропустил или совершил ошибку. Или, возможно, это связано с PHP с использованием кодировки символов, где C++ является сырым битовым потоком. PHP-скрипт настроен на использование простого текстового вывода с кодировкой «us-ascii».

Вот PHP класс:

define('NUM_STRINGS', 256); 

class CTwEncryption 
{ 
    function Crypt($szValue, $szSalt) 
    { 
     $iValueSize = (int)strlen($szValue); 
     $iSaltSize = (int)strlen($szSalt); 

     $szStrings = array(); 
     $szKeys  = array(); 

     $j = 1; 

     // Init array of 0-255 
     for ($i = 0; $i < NUM_STRINGS; $i++) 
      $szStrings[ $i ] = $i; 

     // Init array of 0-255 with a calculated char value 
     for ($i = 0; $i < NUM_STRINGS; $i++) 
     { 
      if ($j > $iSaltSize) 
       $j = 1; 

      $szKeys[ $i ] = ord(substr($szSalt, $j, 1)); 
      $j++; 
     } 

     // Shuffle the array values around to give a random value 
     $j = 0; 
     for ($i = 0; $i < NUM_STRINGS; $i++) 
     { 
      $j = ($j + $szStrings[ $i ] + $szKeys[ $i ]) % NUM_STRINGS; 

      $szTemp = $szStrings[ $i ]; 
      $szStrings[ $i ] = $szStrings[ $j ]; 
      $szStrings[ $j ] = $szTemp; 
     } 

     // Encrypt/decrypt the string 
     $szReturnValue = null; 
     $i = 0; 
     $j = 0; 

     for ($x = 0; $x < $iValueSize; $x++) 
     { 
      $i = ($i + 1) % NUM_STRINGS; 
      $j = ($j + $szStrings[ $i ]) % NUM_STRINGS; 

      $szTemp = $szStrings[ $i ]; 
      $szStrings[ $i ] = $szStrings[ $j ]; 
      $szStrings[ $j ] = $szTemp; 

      $t = ($szStrings[ $i ] + ($szStrings[ $j ] % NUM_STRINGS)) % NUM_STRINGS; 
      $y = $szStrings[ $t ]; 

      $cCrypt = chr(substr($szValue, $x, 1)^$y); 
      $szReturnValue .= $cCrypt; 
     } 

     // Return encrypted/decrypted string 
     return $szReturnValue; 
    } 
} 

Вот класс C++:

#define NUM_STRINGS 256 

class CTwEncryption 
{ 
private: 
    char *szWorking; 

public: 
    CTwEncryption()  { szWorking = NULL; }; 
    ~CTwEncryption() { if (szWorking != NULL) { delete szWorking; szWorking = NULL; } }; 

    char *Crypt(const char szValue[], const char szSalt[]) 
    { 
     const int iValueSize = (int)strlen(szValue); 
     const int iSaltSize = (int)strlen(szSalt); 

     if (iValueSize == 0 || iSaltSize == 0) 
      return NULL; 

     int j = 1; 

     char *szStrings[ NUM_STRINGS ]; 
     char *szKeys[ NUM_STRINGS ]; 

     // Init array of 0-255 
     for (int i = 0; i < NUM_STRINGS; i++) 
     { 
      char *szString = new char[ iValueSize + 1 ]; 

      itoa(i, szString, 10); 
      szString[ iValueSize ] = 0; 

      szStrings[ i ] = szString; 
     } 

     // Init array of 0-255 with a calculated char value 
     for (int i = 0; i < NUM_STRINGS; i++) 
     { 
      char *szKey = new char[ iValueSize + 1 ]; 

      if (j > iSaltSize) 
       j = 1; 

      itoa((int)(szSalt[ j ]), szKey, 10); 
      szKey[ iValueSize ] = 0; 

      szKeys[ i ] = szKey; 
      j++; 
     } 

     // Shuffle the array values around to give a random value 
     j = 0; 
     for (int i = 0; i < NUM_STRINGS; i++) 
     { 
      j = (j + atoi(szStrings[ i ]) + atoi(szKeys[ i ])) % NUM_STRINGS; 

      char *szTemp = szStrings[ i ]; 
      szStrings[ i ] = szStrings[ j ]; 
      szStrings[ j ] = szTemp; 
     } 

     // Encrypt/decrypt the string 
     szWorking = new char[ iValueSize + 1 ]; 
     for (int i = 0; i <= iValueSize; i++) 
      szWorking[ i ] = 0; 

     int i = 0; 
     j = 0; 

     for (int x = 0; x <= iValueSize; x++) 
     { 
      i = (i + 1) % NUM_STRINGS; 
      j = (j + atoi(szStrings[ i ])) % NUM_STRINGS; 

      char *szTemp = szStrings[ i ]; 
      szStrings[ i ] = szStrings[ j ]; 
      szStrings[ j ] = szTemp; 

      int t = (atoi(szStrings[ i ]) + (atoi(szStrings[ j ]) % NUM_STRINGS)) % NUM_STRINGS; 
      int y = atoi(szStrings[ t ]); 

      char cCrypt = char((int)(szValue[ x ])^y); 
      szWorking[ x ] = cCrypt; 
     } 

     // Clean dynamic memory 
     for (int i = 0; i < NUM_STRINGS; i++) 
     { 
      delete szStrings[ i ]; 
      delete szKeys[ i ]; 

      szStrings[ i ] = NULL; 
      szKeys[ i ] = NULL; 
     } 

     // Return encrypted/decrypted string 
     szWorking[ iValueSize ] = 0; 
     return szWorking; 
    } 
}; 

Любая помощь здесь будут оценены, спасибо :)

+4

StackOverflow не является бесплатной службой отладки. – Jon

+5

Какая отладка вы сделали? Вы подтвердили, что все промежуточные переменные имеют эквивалентные значения в PHP и C++? –

+0

Считаете ли вы использование чего-то вроде [phpseclib] (http://phpseclib.sourceforge.net/) для реализаций стандартных методов шифрования pure-PHP, для которых встроены многие другие языки? Это намного проще (и, вероятно, более эффективно), чем пытаться перевернуть свой собственный ... – DaveRandom

ответ

0

Понял это. Похоже, мне нужно отправить вход в скрипт PHP через HTTP-запрос PUT и прочитать его с помощью fopen («php: // input», «rb»). Похоже, что PHP не защищал все в двоичной форме. Также как на C++, так и на PHP я обрабатываю каждый символ как целое число, которое должно корректно обрабатывать строки UTF-32 в двоичном безопасном режиме.

Вот мой класс C++, у меня есть мой в «twencrypt.h»:

#ifndef TWCRYPT_H 
#define TWCRYPT_H 

/*** 
* 
* Two-way string encryption 
* This will encrypt/decrypt a string using a salt. 
* 
* -AdamR 
* 
****/ 

#define NUM_STRINGS 256 

class CTwEncryption 
{ 
private: 
    char *szWorking; 

public: 
    CTwEncryption()  { szWorking = NULL; }; 
    ~CTwEncryption() { if (szWorking != NULL) { delete szWorking; szWorking = NULL; } }; 

    char *Crypt(const char szValue[], const char szSalt[]) 
    { 
     const int iValueSize = (int)strlen(szValue); 
     const int iSaltSize = (int)strlen(szSalt); 

     if (iValueSize < 1 || iSaltSize < 1) 
      return NULL; 

     int j = 1; 

     int iChars[ NUM_STRINGS ]; 
     int iKeys[ NUM_STRINGS ]; 

     // Init array of 0-255 
     for (int i = 0; i < NUM_STRINGS; i++) 
      iChars[ i ] = i; 

     // Init array of 0-255 with a calculated char value 
     for (int i = 0; i < NUM_STRINGS; i++) 
     { 
      if (j > iSaltSize) 
       j = 1; 

      iKeys[ i ] = szSalt[ j ]; 
      j++; 
     } 

     // Shuffle the array values around to give a random value 
     j = 0; 
     for (int i = 0; i < NUM_STRINGS; i++) 
     { 
      j = (j + iChars[ i ] + iKeys[ i ]) % NUM_STRINGS; 

      int iTemp = iChars[ i ]; 
      iChars[ i ] = iChars[ j ]; 
      iChars[ j ] = iTemp; 
     } 

     // Encrypt/decrypt the string 
     szWorking = new char[ iValueSize + 1 ]; 
     for (int i = 0; i <= iValueSize; i++) 
      szWorking[ i ] = 0; 

     int i = 0; 
     j = 0; 

     for (int x = 0; x <= iValueSize; x++) 
     { 
      i = (i + 1) % NUM_STRINGS; 
      j = (j + iChars[ i ]) % NUM_STRINGS; 

      int iTemp = iChars[ i ]; 
      iChars[ i ] = iChars[ j ]; 
      iChars[ j ] = iTemp; 

      int t = (iChars[ i ] + (iChars[ j ] % NUM_STRINGS)) % NUM_STRINGS; 
      int y = iChars[ t ]; 

      char cCrypt = char((int)(szValue[ x ])^y); 
      szWorking[ x ] = cCrypt; 
     } 

     // Return encrypted/decrypted string 
     szWorking[ iValueSize ] = 0; 
     return szWorking; 
    } 
}; 

#endif 

Как она возвращает указатель обугленного Я рекомендую вам использовать STRCPY(), чтобы поместить его в безопасном месте. Вот пример, и в виду, что один и тот же код используется для дешифрования строки.

const char *szString = "My string to encrypt"; 
const char *szSalt = "Some salt here :D"; 
int iStringSize  = (int)strlen(szString); 

char *szEncrypted = new char(iStringSize) + 1); 
CTwEncryption *pTwCrypt = new CTwEncryption(); 
strcpy(szEncrypted, pTwCrypt->Crypt(szString, szSalt); 
szEncrypted[ iStringSize ] = 0; 
delete pTwCrypt; 

Вот мой PHP класс:

<?php 
    define('NUM_STRINGS', 256); 

    class CTwEncryption 
    { 
     function Crypt($szValue, $szSalt) 
     { 
      $iValueSize = strlen($szValue); 
      $iSaltSize = strlen($szSalt); 

      if ($iValueSize == 0 || $iSaltSize == 0) 
       return null; 

      $j = 1; 

      $iChars = array(); 
      $iKeys = array(); 

      // Init array of 0-255 
      for ($i = 0; $i < NUM_STRINGS; $i++) 
       $iChars[ $i ] = $i; 

      // Init array of 0-255 with a calculated char value 
      for ($i = 0; $i < NUM_STRINGS; $i++) 
      { 
       if ($j > $iSaltSize) 
        $j = 1; 

       $iKeys[ $i ] = ord($szSalt[ $j ]); 
       $j++; 
      } 

      // Shuffle the array values around to give a random value 
      $j = 0; 
      for ($i = 0; $i < NUM_STRINGS; $i++) 
      { 
       $j = ($j + $iChars[ $i ] + $iKeys[ $i ]) % NUM_STRINGS; 

       $iTemp = $iChars[ $i ]; 
       $iChars[ $i ] = $iChars[ $j ]; 
       $iChars[ $j ] = $iTemp; 
      } 

      // Encrypt/decrypt the string 
      $szReturnValue = null; 
      $i = 0; 
      $j = 0; 

      for ($x = 0; $x < $iValueSize; $x++) 
      { 
       $i = ($i + 1) % NUM_STRINGS; 
       $j = ($j + $iChars[ $i ]) % NUM_STRINGS; 

       $iTemp = $iChars[ $i ]; 
       $iChars[ $i ] = $iChars[ $j ]; 
       $iChars[ $j ] = $iTemp; 

       $t = ($iChars[ $i ] + ($iChars[ $j ] % NUM_STRINGS)) % NUM_STRINGS; 
       $y = $iChars[ $t ]; 

       $iValue = str_split($szValue); 
       for ($c = 0; $c < $iValueSize; $c++) 
        $iValue[ $c ] = ord($iValue[ $c ]); 

       $cCrypt = chr($iValue[ $x ]^$y); 
       $szReturnValue .= $cCrypt; 
      } 

      // Return encrypted/decrypted string 
      return $szReturnValue; 
     } 
    } 

    $c_TwEncryption = new CTwEncryption; 
?> 

Это один немного проще в использовании. Это просто:

$szString = "My string to hide lollercoaster"; 
$szSalt  = "super duper password of doom"; 

$szEncrypted = $c_TwEncryption->Crypt($szString, $szSalt); 
$szDecrypted = $c_TwEncryption->Crypt($szEncrypted, $szSalt); 

Помните, что вы не должны определить $ szString или $ szSalt (PHP сторона) с помощью запроса HTTP GET или POST. Будьте в безопасности и используйте запрос PUT и прочитайте следующее:

$szString = null; 
$hInData = fopen("php://input", "rb") || die("Unable to open HTTP PUT handle."); 

if($hInData != null) 
{ 
    while ($bData = fread($hRequest, 1024)) 
     $szString .= $bData; 
} 
else 
    die("Unable to read HTTP PUT data."); 

fClose($hInData) || die("Unable to close HTTP PUT handle."); 

if($szString == null || empty($szString)) 
    die("No data read from HTTP PUT stream."); 

Наслаждайтесь.

1

Я не уверен, но возможно, используя функции mb_* могут помочь:

  • вместо того, чтобы использовать strlenmb_strlen
  • вместо использования substrmb_substr

Либо дать ему только значение, или также кодирование (но каждая mb_* функция должна проверить для кодирования строки, если никто не предусмотрен).

+0

А хорошая идея есть. Установил расширение mbstring и использовал их, хотя скрипт PHP дал тот же результат. – Adambean

+0

@Adambean Затем, как уже упоминалось выше, вы должны выполнить пошаговую (** переменную по переменной **) отладку ** обоих сценариев ** и увидеть **, где сначала происходит различие и почему **. – shadyyx

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