字符串数组的字节操作

时间:2014-10-28 19:37:54

标签: c# php

这个问题是我解决的上一个问题的后续问题:

manipulating bytes in a binary string

在那个问题中,我解释说我在php和c#之间有一个有效的加密通信。我添加了一个轻微的字节调整,以增加默默无闻的水平。然而,我注意到大约50次中有1次无法理解加密内容。这让我相信我的字节更改和字节恢复代码不能解决某些边缘情况。

请注意,我一遍又一遍地使用相同的消息对此进行测试,因此唯一改变的是每次随机化并附加在加密数据前面的IV。

以下是我在PHP端加密响应的内容。我们的想法是将字符翻滚5,考虑到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;

这就是我在C#端做的事情,它在从http响应中获取Base64字符串后解密响应

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

其中FromBase64ServerString定义为

//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);

概要 - 加密代码本身可以正常工作 - 在加密之后和解密之前添加字节inc \ dec以反转它只会导致5%的时间出现问题。 - 删除字节摆弄并让它整天来回传递垃圾邮件会导致错误。

2 个答案:

答案 0 :(得分:2)

我认为问题出现是因为PHP代码中的else if($ordVal == 45)+的正确ASCII 43 而不是45(45是{{1} }字符)导致C#端错误地解码字符串。将PHP代码更改为以下代码段可以解决问题。

-

答案 1 :(得分:0)

我认为你必须得到碰撞。如果序数 - 产生你的一个特殊字符,那么如果正确你就不会反转。