Xor Key Encryption Help

Just starting out? Need help? Post your questions and find answers here.
jeslar360
User
User
Posts: 20
Joined: Thu Aug 28, 2008 6:24 am

Xor Key Encryption Help

Post by jeslar360 »

I found the original function here:

viewtopic.php?t=37017

Well, I tried to modify it so it could output Base64 code (to help with storing encrypted text in a file)...but while I can encrypt it just fine...I can't seem to reverse it.

Here is my modified version:

Code: Select all

Procedure.s EncryptText(text.s, pw.s)
  InputText.s   = text
  UseKey.s      = pw.s
  InLength      = StringByteLength(text)
  OutLength     = InLength * 2
  OutText.s     = Space(OutLength)
  *Buffer       = @InputText
  
  Protected i, Byte.b, KeyByte.b
  Protected KeyLength = Len(Key$), KeyPos
  
  For i = 0 To InLength-1
    Byte    = PeekB(*Buffer+i)
    KeyByte = PeekB(@UseKey+KeyPos)
    Byte ! KeyByte ! Len ! i ! KeyLength
    PokeB(*Buffer+i,Byte)
    KeyPos + 1
    If KeyPos > KeyLength
      KeyPos = 0
    EndIf
  Next
  Base64Encoder(@InputText, InLength, @OutText, OutLength)
  ProcedureReturn OutText
EndProcedure
And here is one of the MANY attempts to reverse it...

Code: Select all

Procedure.s DecryptText(text.s, pw.s)
  InputText.s   = text
  UseKey.s      = pw.s
  InLength      = StringByteLength(text)
  OutLength     = InLingth  * 0.75
  OutText.s     = Space(OutLength)
  
  Base64Decoder(@InputText, InLength, @OutText, OutLength)
  
  Length        = StringByteLength(OutText)
  
  *Buffer       = @OutText
  
  Protected i, Byte.b, KeyByte.b
  Protected KeyLength = Len(Key$), KeyPos
  
  For i = 0 To Length-1
    Byte    = PeekB(*Buffer+i)
    KeyByte = PeekB(@UseKey+KeyPos)
    Byte ! KeyByte ! Len ! i ! KeyLength
    PokeB(*Buffer+i,Byte)
    KeyPos + 1
    If KeyPos > KeyLength
      KeyPos = 0
    EndIf
  Next
  ProcedureReturn OutText
EndProcedure
When testing it, I used the text "Hello World" and the password "somepass"

The encrypted text came out as "OxcdHBhWIhsJFh0="

however, the attempt using the second function to REVERSE it, came out with: "PAoSFD80HSMyEgoyORZNQQ=="

Could someone PLEASE help me?
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Xor Key Encryption Help

Post by luis »

Code: Select all

OutLength     = InLingth  * 0.75 
InLingth ?

And how can you run this ? Doesn't work. The debugger stops with an error in the decode. :?:

Correcting the variable name made it work here.

Code: Select all

a$ = EncryptText("Hello World","somepass")
Debug a$
b$ = DecryptText(a$, "somepass") 
Debug b$ 
Output

Code: Select all

[00:57:51] OxcdHBhWIhsJFh0=
[00:57:51] Hello World
"Have you tried turning it off and on again ?"
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Xor Key Encryption Help

Post by netmaestro »

This is fun to play with, here's mine to join the multitude:

Code: Select all

Procedure.s EncryptText(text$, key$)
  Protected keylen = Len(key$), cc, result$
  *keyptr.character = @key$
  *readptr.character = @text$
  *encrypted.character = AllocateMemory(Len(text$))
  *writeptr.Character = *encrypted
  While *readptr\c
    *writeptr\c = *readptr\c ! *keyptr\c ! keylen
    *keyptr = @key$ + cc%keylen
    *readptr+1 : *writeptr+1 : cc+1
  Wend
  *result = AllocateMemory(MemorySize(*encrypted)*1.4)
  Base64Encoder(*encrypted, MemorySize(*encrypted),*result, MemorySize(*result))
  result$ = PeekS(*result)
  FreeMemory(*encrypted)
  FreeMemory(*result)
  ProcedureReturn result$
EndProcedure

Procedure.s DecryptText(text$, key$)
  Protected keylen = Len(key$), cc, size, result$
  *encrypted.character = AllocateMemory(Len(text$))
  size = Base64Decoder(@text$, Len(text$), *encrypted, MemorySize(*encrypted))
  *decrypted = AllocateMemory(size)
  *keyptr.character = @key$
  *readptr.character = *encrypted
  *writeptr.Character = *decrypted
  While *readptr\c
    *writeptr\c = *readptr\c ! *keyptr\c ! keylen
    *keyptr = @key$ + cc%keylen
    *readptr+1 : *writeptr+1 : cc+1
  Wend
  result$ = PeekS(*decrypted, size)
  FreeMemory(*encrypted)
  FreeMemory(*decrypted)
  ProcedureReturn result$
EndProcedure


a$ = EncryptText("Hello world!", "mykey")
Debug a$
b$ = DecryptText(a$,"mykey")
Debug b$
BERESHEIT
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Xor Key Encryption Help

Post by Demivec »

netmaestro wrote:This is fun to play with, here's mine to join the multitude:
Thanks for the contribution.

I haven't examined your version in depth but I did notice some things in your code that may cause problems.

It would seem you would need to make sure that in the EncryptText() routine you would need to make sure the result buffer is at least a minimum of 64 bytes (according to the documentation of Base64Encoder() ). Your example also allocates memory based on the length of the text without any regard for the character size and so would probably run into problems with unicode.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Xor Key Encryption Help

Post by netmaestro »

Thanks for the heads-up! I use Base64 encoding so little I didn't even know about the 64 byte minimum :oops: As to unicode, I didn't consider it for this as it's just something to play with, not really meant to be a production solution. I'm sure for that purpose, others have shared more comprehensive approaches. I always appreciate your input, as you usually think of things that didn't occur to me :mrgreen:
BERESHEIT
jeslar360
User
User
Posts: 20
Joined: Thu Aug 28, 2008 6:24 am

Re: Xor Key Encryption Help

Post by jeslar360 »

Thank you all for your input, and help. I know that this encryption is not much up to production level par, but it should be enough for what I am intending it for. I am working on a Journal app, that can be used by multiple people. My intent was to use an SQLite database to keep track of the users (Name, and Password, the password would be padded with extra info, and either an SHA1 or MD5 fingerprint stored for the password. To keep the data safe, I was going to make each "Journal" a separate SQLite database, with the content encrypted using the password (but for the content encryption, the fingerprint would either be of the other type, OR have different padding, or both. That new fingerprinted password would be used to "Encrypt" the entry...

Thats why I wanted to make the function output Base64, I am not sure how well SQLite will behave with some of the weird characters that the were showing up before trying to do that..

Still can't get mine to work (and I am wondering about this Base64Encoder minimum byte length thing...I was able to get an encrypted output with just 1, 2, 3, or 4 characters...wonder if I am missing something...

Anyway, the Journal app is gonna be a free app for anyone to use, when/if I can get it completed... Anyone interested in a copy when/if I manage to get it done?
Zach
Addict
Addict
Posts: 1676
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Xor Key Encryption Help

Post by Zach »

I'm using the same Proc you based your attempts on (unmodified) and I have also pondered the whole idea of encrypting the encryption key - but I arrived at the conclusion "what was the point?", which may just be based on a lack of knowledge (I don't even really understand encryption, or how to properly use it).

It seems like if your concern is someone getting access to the key, you still end up with a key they can find via some kind of runtime tool, in which case the whole point of the extra encryption steps seems pointless?

The best I could come up with, is to build the key based on several other constants that would not change in the program source code (kind of like those anti-spam Javascripts which peice the e-mail address together by combining a+b+c+d etc..)
User avatar
idle
Always Here
Always Here
Posts: 5928
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Xor Key Encryption Help

Post by idle »

You can hide a key fairly easily by making a random PAD
Master Key is only know to the server
Private key is the clients encrypted key it is encoded into the PAD from Master ! Public
Public key is the users login string

You would need to verify the pad to ensure it didn't get a collision in the encoding

Code: Select all

;create a pad file 2048 bytes long use the master key ! Public and uses a CRC fed back on itself to get an index
;into the random PAD and write the byte of the privatekey

Procedure hidekey(MasterKey.s,publicKey.s,privateKey.s,seed=12345)
  Protected result.q,MasterPublic.s
  result = seed
  fn = OpenFile(#PB_Any,"randomfile.dat")
  If fn
    For a = 0 To 2048
        WriteByte(fn,Random(42)+48) 
    Next
   For a = 1 To Len(MasterKey)
       MasterPublic + Chr(PeekC(@MasterKey+a) ! PeekC(@publicKey+a))    
   Next 
    
    For a = 1 To Len(MasterKey)
      result = CRC32Fingerprint(@MasterPublic,Len(MasterKey),result) & $FFFFFF
      result % 2048
      FileSeek(fn,result)
      byte = Asc(Mid(privatekey,a,1))
      WriteByte(fn,byte)
    Next
    CloseFile(fn)
EndIf   
EndProcedure     

Procedure.s GetKey(MasterKey.s,publicKey.s,seed=12345)
  Protected key.s,result.q,MasterPublic.s
  result=seed 
  fn = OpenFile(#PB_Any,"randomfile.dat")
  For a = 1 To Len(MasterKey)
      MasterPublic + Chr(PeekC(@MasterKey+a) ! PeekC(@publicKey+a))    
  Next 
    
  If fn
    For a = 1 To Len(MasterKey)
      result = CRC32Fingerprint(@MasterPublic,Len(MasterKey),result) & $FFFFFF
      result % 2048
      FileSeek(fn,result)
      key + Chr(ReadByte(fn))
  Next
  CloseFile(fn)
EndIf   

ProcedureReturn key
   
EndProcedure 

Define MasterKey.s,privatekey.s,PublicKey.s
Global dump.s=Space(2048)

MasterKey = MD5Fingerprint(@"Secret key",10)
privatekey = MD5Fingerprint(@"Users key",9)
publickey = MD5Fingerprint(@"bob@billbob.com",15)

hidekey(MasterKey,PublicKey,privatekey)

fn = OpenFile(#PB_Any,"randomfile.dat")
ReadData(fn,@dump,2048)
Debug dump
CloseFile(fn)
Debug "---------------------------------------------------"

Debug getkey(MasterKey,PublicKey)

Debug privatekey 
Windows 11, Manjaro, Raspberry Pi OS
Image
Zach
Addict
Addict
Posts: 1676
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Xor Key Encryption Help

Post by Zach »

Yes I did some reading earlier this morning, and I guess that is the real crux of the issue.

The dual keys, etc work great for client/server setups, but in my case when working with a purely client-side app there is no true way to 100% secure it.

I've kind of come to terms with that though.
User avatar
idle
Always Here
Always Here
Posts: 5928
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Xor Key Encryption Help

Post by idle »

On the client side only, you're pretty much stuffed.
All you can do is make it more difficult for someone to find or extract the master key.
The Master key can be generated in code from the pad itself, so it would be unique to each system.
It won't be readily available to discover unless someone has the intent to use a debugger.
Though you really need to ask yourself, would someone really bother to go to the trouble of debugging the code?
Then all you could do is obscure the code to access the keys using things like using multiple calls, time traps
scatter and gather tactics via threads and random branching to useless code to waste a would be debuggers time.
It's not really worth the effort.
Windows 11, Manjaro, Raspberry Pi OS
Image
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: Xor Key Encryption Help

Post by xakep »

What about this one:

Code: Select all

Procedure.s XOREncryption(DataIn.s, CodeKey.s)
  Protected lonDataPtr.i, intXOrValue1.i, intXOrValue2.i, Temp.i, strDataOut.s
  
  
  For lonDataPtr = 1 To Len(DataIn)
    intXOrValue1 = Asc(Mid(DataIn, lonDataPtr, 1))
    intXOrValue2 = Asc(Mid(CodeKey, ((lonDataPtr % Len(CodeKey)) + 1), 1))
    
    Temp = (intXOrValue1 ! intXOrValue2)
    
    strDataOut = strDataOut + RSet(Hex(temp), 2, "0")
  Next
  
  ProcedureReturn strDataOut
EndProcedure

Procedure.s XorDecryption(DataIn.s, CodeKey.s)
  Protected lonDataPtr.i, intXOrValue1.i, intXOrValue2.i, strDataOut.s
  
  For lonDataPtr = 1 To (Len(DataIn) / 2)
    intXOrValue1 = Val("$" + Mid(DataIn, (2 * lonDataPtr) - 1, 2))
    intXOrValue2 = Asc(Mid(CodeKey, ((lonDataPtr % Len(CodeKey)) + 1), 1))
    
    strDataOut = strDataOut + Chr(intXOrValue1 ! intXOrValue2)
  Next
  
  ProcedureReturn strDataOut
EndProcedure

Define.s txt, key, crypted, decrypted

txt = "Hello there, first PB snippet &*(!^&$*("
key = "abc"


crypted = XOREncryption(txt, key)
decrypted = XorDecryption(crypted, key)

Debug "Crypted:" + crypted
Debug "Decrypted:" + decrypted
Just translated this from vb6, the good thing is it doesn't need base64 as the output is allways printable. ( but the output will be double of the input)
Maybe someone can make it faster, if time is available. (i'm very beginner in PB. switched from VB6).

Thanks for your time.
Post Reply