Recent

Author Topic: XOR with special characters  (Read 10273 times)

fjabouley

  • Full Member
  • ***
  • Posts: 129
XOR with special characters
« on: August 18, 2016, 01:37:24 pm »
Hello !!!
I've made a very small function to quickly encrypt some strings using xor (I don't need high security) :

Code: Pascal  [Select][+][-]
  1. function encodetexte(texte, mdp: string):string;
  2. var
  3.   ch1,ch2,key:byte;
  4.   x,idx:integer;
  5.   new:string;
  6. begin
  7.   key:=0;ch1:=0;ch2:= 0;
  8.   for x := 1 to length(texte) do
  9.   begin
  10.     ch1:=byte(texte[x]);
  11.     idx:= (x mod Length(mdp) + 1);
  12.     key := byte(mdp[idx]);
  13.     ch2:= (ch1 xor key);
  14.     new:=new+chr(ch2);
  15.   end;
  16.   result:=(new);
  17. end;

It works well... until I use special characters like ("ç",'é", etc.... which happens frequently because I'm french  ;) ...)
I think my string encoding is wrong, but do you know what I need to do to make it work ?
Thanks a lot !!!

Regards
« Last Edit: August 18, 2016, 01:39:35 pm by jabounet »

derek.john.evans

  • Guest
Re: XOR with special characters
« Reply #1 on: August 18, 2016, 02:28:27 pm »
Unsure but, the code to access  mdp looks incorrect.

mdp is a Pascal string, so access is 1..length(s)
Your mod returns 0..length(s)

So, should the code be?

Code: Pascal  [Select][+][-]
  1.     idx:= x mod Length(mdp);
  2.     key := byte(mdp[idx + 1]);
  3.  

derek.john.evans

  • Guest
Re: XOR with special characters
« Reply #2 on: August 18, 2016, 02:32:25 pm »
Also chr() might only handle valid ASCII. Try a hard type cast

Code: Pascal  [Select][+][-]
  1. new:=new+char(ch2);
  2.  

fjabouley

  • Full Member
  • ***
  • Posts: 129
Re: XOR with special characters
« Reply #3 on: August 18, 2016, 02:39:32 pm »
...hmm, no it doesn't work with char()..
The function works well with no special characters
Thanx !

fjabouley

  • Full Member
  • ***
  • Posts: 129
Re: XOR with special characters
« Reply #4 on: August 18, 2016, 02:43:39 pm »
I don't understand the difference between :

idx:= x mod Length(mdp);
key := byte(mdp[idx + 1]);

and :

idx:= (x mod Length(mdp) + 1);
key := byte(mdp[idx]);
   
To me, it's the same ?

Fungus

  • Sr. Member
  • ****
  • Posts: 354
Re: XOR with special characters
« Reply #5 on: August 18, 2016, 02:46:23 pm »
It is because special characters are UTF-8 encoded and this means that one character takes up multiple bytes. Adding a partial UFT-8 character will result in failure and you do that in line 14 (new:=new+chr(ch2)). Also, your encryption might trigger unwanted UTF-8 sequences when stored back to a string. You must encrypt to a buffer (of bytes) and process it from there. If you want it as text you could Base64 encode the buffer.

Code: Pascal  [Select][+][-]
  1. Procedure XorCrypt(Var Buffer; Const Len: Cardinal; Const Key: String);
  2. Var PB: ^Byte;
  3.     I, II: Cardinal; //Changed from integer to cardinal
  4. Begin
  5.   PB:= @Buffer;
  6.   II:= 1;
  7.   For I:= 0 To Len - 1 Do Begin
  8.     PB^:= PB^ Xor Byte(Key[II]);
  9.     Inc(PB);
  10.     Inc(II);
  11.     If II > Length(Key) Then II:= 1;
  12.   End;
  13. End;
  14.  
  15. Procedure TestEncryption;
  16. Var S, K: String;
  17.     P: Pointer;
  18.     L: Cardinal;
  19. Begin
  20.  
  21.   S:= 'This is a string to encrypt, it contains UTF-8 characters, like æøåéç :-)';
  22.   K:= 'This is secret! Shhhh!';
  23.  
  24.   //Encryption
  25.   L:= Length(S);
  26.   GetMem(P, L);
  27.   Move(S[1], P^, L);
  28.   XorCrypt(P^, L, K);
  29.  
  30.   //The memory P is now an encrypted version of our string
  31.   //Here you could encode it to Base64 to get is as a string
  32.  
  33.   //Clear string to proof concept
  34.   S:= '';
  35.  
  36.   //Decryption / reverse engineer
  37.   XorCrypt(P^, L, K);
  38.   SetString(S, PAnsiChar(P), L);
  39.  
  40.   //Show da sh!t!
  41.   SHowMessage(S);
  42.  
  43.   //Cleanup
  44.   FreeMem(P);
  45.  
  46. end;
« Last Edit: August 18, 2016, 02:56:08 pm by Fungus »

fjabouley

  • Full Member
  • ***
  • Posts: 129
Re: XOR with special characters
« Reply #6 on: August 18, 2016, 03:56:35 pm »
I'm going to try this.
Thank you very much !!!!

Fungus

  • Sr. Member
  • ****
  • Posts: 354
Re: XOR with special characters
« Reply #7 on: August 18, 2016, 05:29:49 pm »
Good luck, your own function might also work if you change all "string" types to "rawbytestring" - but you should never store binary data in strings - they are intended for text :-)

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: XOR with special characters
« Reply #8 on: August 18, 2016, 05:41:06 pm »
FPC already has those functions XorEncode and XorDecode; using those will save a lot of headaches.

Fungus

  • Sr. Member
  • ****
  • Posts: 354
Re: XOR with special characters
« Reply #9 on: August 18, 2016, 07:16:36 pm »
FPC already has those functions XorEncode and XorDecode; using those will save a lot of headaches.

A result as hex-value might not be usefull. At least it will take up double the space :-)

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: XOR with special characters
« Reply #10 on: August 18, 2016, 07:29:37 pm »
A result as hex-value might not be usefull. At least it will take up double the space :-)
I'll just quote from XorString page (apply here):
Quote
The resulting string may contain unreadable characters and may even contain null characters. For this reason it may be a better idea to use the XorEncode function instead, which will representing each resulting ASCII code as a hexadecimal number (of length 2).

Fungus

  • Sr. Member
  • ****
  • Posts: 354
Re: XOR with special characters
« Reply #11 on: August 18, 2016, 07:38:14 pm »
I'll just quote from XorString page (apply here):
Quote
The resulting string may contain unreadable characters and may even contain null characters. For this reason it may be a better idea to use the XorEncode function instead, which will representing each resulting ASCII code as a hexadecimal number (of length 2).

If the encoded/encrypted string is saved to a binary file a hex-representation is IMHO useless. And for displaying as text I'd prefer Base64 over hex (almost) anytime :-)

But nice to know that FPC has actual functions for doing stuff like that ;-)

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: XOR with special characters
« Reply #12 on: August 18, 2016, 08:17:41 pm »
If the encoded/encrypted string is saved to a binary file a hex-representation is IMHO useless. And for displaying as text I'd prefer Base64 over hex (almost) anytime :-)
Looking at his function function encodetexte(texte, mdp: string):string; he returns string and so, I don't think returning binary inside string (may contain invalid characters) here is good idea (maybe I'm wrong); using base64 is also valid.

anyway; he could take look at the XorEncode/XorDecode (not complicated) and create his own Encoding/Decoding function  :) .

fjabouley

  • Full Member
  • ***
  • Posts: 129
Re: XOR with special characters
« Reply #13 on: August 18, 2016, 11:33:58 pm »
Thank you so much guys !
As always, everybody in this forum is awesome.
I think I'll use native functions (xorencode/decode) although I wanted to put encrypted strings into a database (it will be larger to store)
I was seeking an answer thinking it was possible to find an equivalent to ord(),chr()... with an utf-8 string... I was wrong, it's not so easy to manipulate those strings :)


Thanks again !


Fungus

  • Sr. Member
  • ****
  • Posts: 354
Re: XOR with special characters
« Reply #14 on: August 19, 2016, 02:16:24 pm »
If I where you I'd still use Base64 instead of hex:

Code: Pascal  [Select][+][-]
  1. Procedure XorCrypt(Var Buffer; Const Len: Cardinal; Const Key: String);
  2. Var PB: ^Byte;
  3.     I, II: Cardinal;
  4. Begin
  5.   PB:= @Buffer;
  6.   II:= 1;
  7.   For I:= 0 To Len - 1 Do Begin
  8.     PB^:= PB^ Xor Byte(Key[II]);
  9.     Inc(PB);
  10.     Inc(II);
  11.     If II > Length(Key) Then II:= 1;
  12.   End;
  13. End;
  14.  
  15. Function XorEncodeBase64(Const What, Key: String): String;
  16. Var P: Pointer;
  17.     L: Cardinal;
  18.     M: TMemoryStream;
  19. Begin
  20.   //Uses Base64
  21.   L:= Length(What);
  22.   GetMem(P, L);
  23.   Try
  24.     Move(What[1], P^, L);
  25.     XorCrypt(P^, L, Key);
  26.     M:= TMemoryStream.Create;
  27.     Try
  28.       With TBase64EncodingStream.Create(M) Do Try
  29.         Write(P^, L);
  30.       Finally
  31.         Free;
  32.       End;
  33.       SetString(Result, PAnsiChar(M.Memory), M.Size);
  34.     Finally
  35.       M.Free;
  36.     End;
  37.   Finally
  38.     FreeMem(P);
  39.   End;
  40. End;
  41.  
  42. Function XorDecodeBase64(Const What, Key: String): String;
  43. Var P: Pointer;
  44.     L: Cardinal;
  45.     M: TMemoryStream;
  46. Begin
  47.   //Uses Base64
  48.   M:= TMemoryStream.Create;
  49.   Try
  50.     M.Write(What[1], Length(What));
  51.     M.Position:= 0;
  52.     GetMem(P, M.Size);
  53.     Try
  54.       With TBase64DecodingStream.Create(M) Do Try
  55.         L:= Read(P^, M.Size);
  56.         XorCrypt(P^, L, Key);
  57.         SetString(Result, PAnsiChar(P), L);
  58.       Finally
  59.         Free;
  60.       End;
  61.     Finally
  62.       FreeMem(P);
  63.     End;
  64.   Finally
  65.     M.Free;
  66.   End;
  67. End;
  68.  
  69. Procedure TestXorBase64;
  70. Var S, K, B64: String;
  71. Begin
  72.  
  73.   S:= 'This is a string to encrypt, it contains UTF-8 characters, like æøåéç :-)';
  74.   K:= 'This is secret! Shhhh!';
  75.  
  76.   B64:= XorEncodeBase64(S, K);
  77.   ShowMessage(B64);
  78.  
  79.   S:= XorDecodeBase64(B64, K);
  80.   ShowMessage(S);
  81.  
  82. End;

 

TinyPortal © 2005-2018