简体   繁体   中英

Byte manipulation of string array

This question is a follow up to this previous question that I solved:

manipulating bytes in a binary string

In that question I explained that I have a working encryption communication between php and c#. I added a slight byte tweak to increase the obscurity level just a bit more. I have noticed however that about 1 in 50 times it fails to understand the encrypted content. This leads me to believe that my byte change- and byte revert code is not accounting for some edge case.

Note that I tested this with the same message over and over so the only thing that is changing is the IV which is randomized each time and appended in front of the encrypted data.

Here is what I am doing on the PHP side which encrypts the response. The idea is to roll the character over by 5, accounting for the limitations of base64

$data = getEncryptedBase64Data();
$ordVal = ord($data[strlen($data)-5]);
if($ordVal == 65)//'A'
{
    $ordVal = 47;//'/'
}
else if($ordVal == 48)//'0'
{
    $ordVal = 122;//'z'
}
else if($ordVal == 47)//'/'
{
    $ordVal = 45;//'+'
}
else if($ordVal == 45) //'+'
{
    $ordVal = 57;//'9'
}
else //B through z and 1 through 9
{
    $ordVal--;
}
$data[strlen($data)-5] = chr($ordVal);
return $data;

And here is what I am doing on the C# side which decrypts the response after it gets a Base64 string from the http response

string webText = //The content from the http response
byte[] decoded = Utils.FromBase64ServerString(webText);
//do decryption

where FromBase64ServerString is defined as

//Roll the 5th last bit to make things harder to decrypt
    char[] chars = s.ToCharArray();
    char ordinal = chars[chars.Length - 5];
    if(ordinal == 'z')
    {
        ordinal = '0';
    }
    else if(ordinal == '+')
    {
        ordinal = '/';
    }
    else if(ordinal == '/')
    {
        ordinal = 'A';
    }
    else if(ordinal == '9')
    {
        ordinal = '+';
    }
    else
    {
        ordinal++;
    }
    chars[chars.Length - 5] = ordinal;
    return Convert.FromBase64CharArray(chars,0,chars.Length);

Summary - Encryption code works fine on its own - Adding a byte inc\\dec after encryption and before decryption to reverse it only causes problems 5% of the time or so. - Removing the byte fiddling and letting it spam messages back and forth all day results in no errors.

I believe the problem occurs because else if($ordVal == 45) in PHP code, the correct ASCII value for + is 43 not 45 (45 is - character) which cause the C# side to decode the string incorrectly. changing PHP code to following snippet should solve the problem.

$data = getEncryptedBase64Data();
$ordVal = ord($data[strlen($data)-5]);
if($ordVal == 65)//'A'
{
    $ordVal = 47;//'/'
}
else if($ordVal == 48)//'0'
{
    $ordVal = 122;//'z'
}
else if($ordVal == 47)//'/'
{
    $ordVal = 43;//'+'
}
else if($ordVal == 43) //'+'
{
    $ordVal = 57;//'9'
}
else //B through z and 1 through 9
{
    $ordVal--;
}
$data[strlen($data)-5] = chr($ordVal);
return $data;

I think that you must be getting collisions. If the ordinal-- produces one of your special chars then you will not reverse if correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM