开发者

Python byte per byte XOR decryption

I have an XOR encypted file by a VB.net program using this function to scramble:

Public Class Crypter
    ...
    'This Will convert String to bytes, then call the other function.
    Public Function Crypt(ByVal Data As String) As String
        Return Encoding.Default.GetString(Crypt(Encoding.Default.GetBytes(Data)))
    End Function

    'This calls XorCrypt giving Key converted to bytes
    Public Function Crypt(ByVal Data() As Byte) As Byte()
        Return XorCrypt(Data, Encoding.Default.GetBytes(Me.Key))
    End Function

    'Xor Encryption.
    Private Function XorCrypt(ByVal Data() As Byte, ByVal Key() As Byte) As Byte()
        Dim i As Integer
        If Key.Length <> 0 Then
            For i = 0 To Data.Length - 1
                Data(i) = Data(i) Xor Key(i Mod Key.Length)
            Next
        End If
        Return Data
    End Function
End Class

and saved this way:

Dim Crypter As New Cryptic(Key)
'open destination file
Dim objWriter As New StreamW开发者_如何学编程riter(fileName)
'write crypted content
objWriter.Write(Crypter.Crypt(data))

Now I have to reopen the file with Python but I have troubles getting single bytes, this is the XOR function in python:

def crypto(self, data):
    'crypto(self, data) -> str'
    return ''.join(chr((ord(x) ^ ord(y)) % 256) \
        for (x, y) in izip(data.decode('utf-8'), cycle(self.key))

I had to add the % 256 since sometimes x is > 256 i.e. not a single byte.

This thing of two bytes being passed does not break the decryption because the key keeps "paired" with the following data.

The problem is some decrypted character in the conversion is wrong. These chars are all accented letters like à, è, ì but just a few of the overall accented letters. The others are all correctly restored.

I guess it could be due to the 256 mod but without it I of course get a chr exception...

Thanks for your support


Your decoded data appears to contain unicode characters with values above 256. In Python 2.x chr can only handle values below 256. Use unichr instead of chr and it should work:

return ''.join(unichr((ord(x) ^ ord(y))) \
    for (x, y) in izip(data.decode('utf-8'), cycle(self.key))


is it correct to save scrambled data as string (i.e. re-encoded with default encoding) with StreamWriter? Wouldn't be correct to save bytes directly? Or is it the same thing?

Dim objWriter As New StreamWriter(fileName)
objWriter.Write(Crypter.Crypt(data))

Which Crypter.Crypt is called by StreamWriter.Write?

This

Public Function Crypt(ByVal Data() As Byte) As Byte()

or this?

Public Function Crypt(ByVal Data As String) As String

I'm not handy with Vb.net...


I've run this to get what chars are involved in the right/wrong "²" conversion

for (x, y) in izip(data.decode('utf-8'), cycle(self.key.decode('utf-8'))):
    if (ord(x) ^ ord(y)) > 255 or chr(ord(x) ^ ord(y)) == '\xb2':
        print (x, y, chr((ord(x) ^ ord(y)) % 256),
               unichr(ord(x) ^ ord(y)), ord(x), ord(y))

I got this:

ù K ² ² 249 75
 p ² ² 194 112
Æ t ² ² 198 116
‚ 0 * ‪ 8218 48

the last one is wrong because a double byte is used... but if just one would be passed probably the rest of the decryption would result outh of phase


Indeed, the following line is wrong:

Return Encoding.Default.GetString(Crypt(Encoding.Default.GetBytes(Data)))

There's no general guarantee that the bytes being returned from Crypt are valid to decode as a string. You'd be better using Convert.ToBase64String, and then passing that string to your Python code (where obviously, you'd need to be able to Base-64 decode the bytes.

And as others have pointed out, the level of security XORing provides is adequate to protect your data from, maybe, your little sister.


If you're opening the file in text mode, it might be interpreted as Unicode text. Try opening it in binary mode to make all characters into bytes. That should avoid your issues with chr. If you're using Python 3.x, do remember that when working in binary mode you should be using bytes literals rather than string literals, the latter of which are Unicode strings by design.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜