Author Topic: File encryption / decryption  (Read 5328 times)

0 Members and 1 Guest are viewing this topic.

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
File encryption / decryption
« on: December 06, 2020, 11:48:23 pm »
Basic file encryptor
Don't try this on important files as it has not been tested

**********************

DIM string1(16384) AS STRING 
DIM string2(16384) AS STRING
DIM LFILE AS _UNSIGNED LONG
DIM FPOS AS _UNSIGNED LONG
DIM NBYTES  AS _UNSIGNED LONG
FPOS = 1
string1 = string$(16384,"a") 'string1 could randomized for better security
OPEN TEST.TXT FOR BINARY AS #1

LFILE = LOF (1)

DO
IF LFILE  = 0  THEN EXIT DO
 
  IF LFILE  < 16384  THEN
  GET #1, ,string2(LFILE) 'file read
  FPOS = FPOS  + LFILE    'FPOS = file position after GET
  nbytes = LFILE 
  GOSUB  XORstring2      'encrypt or decrypt
  SEEK 1, FPOS - LFILE    'adjust file pointer 
  PUT #1, ,string2(LFILE) 'file write
  LFILE = 0
  END IF 

  IF LFILE =>16384  THEN
  GET #1, ,string2(16384) 'file read
  FPOS = FPOS  + 16384    'FPOS = file position after GET 
  nbytes = 16384 
  GOSUB XORstring2        'encrypt or decrypt
  SEEK 1, FPOS - 16384    'adjust file pointer
  PUT #1, ,string2(16384) 'file write
  LFILE = LFILE - 16384
  END IF 

LOOP
CLOSE 1
END

XORstring2:
FOR x% = 1 to nbytes
a$ = MID$(string1),x%,1)
b$ = MID$(string2),x%,1)
b$ xor a$
MID$(string2),x%,1) = b$
NEXT x%
RETURN

*****
Question
In the above code is:
DIM string1(16384) AS STRING
equivalent to
DIM string1 AS STRING * 16384
for the application as shown?
****
« Last Edit: December 07, 2020, 06:04:56 pm by NOVARSEG »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: File encryption / decryption
« Reply #1 on: December 08, 2020, 12:35:34 pm »
Quote
*****
Question
In the above code is:
DIM string1(16384) AS STRING
equivalent to
DIM string1 AS STRING * 16384
for the application as shown?
****

Oh man, I just saw this question when I started playing around with a file Encryption of my own.
Sorry but you had it buried in what I thought was code. I saw the XOR code method in quick glance and passed at looking at until I decided to test my encryptor with a copy of your post put in a text file, when decrypting my description I saw the question. Well better late that never...

No, those 2 things are not equivalent:
DIM string1(16384) AS STRING > is a string array with 16384 items
DIM string1 AS STRING * 16384 > is a Fixed string of fixed length 16384

Do you know how to post code in code tabs?  [ code ]  your code here   [ /code ]

  [ You are not allowed to view this attachment ]


Put your code in editor, highlight it all, and then click the QB64 icon button.

or click the button and paste the code between    code] x[/code  where x is (not much room).
« Last Edit: December 08, 2020, 12:47:50 pm by bplus »

Offline Bert22306

  • Forum Regular
  • Posts: 206
    • View Profile
Re: File encryption / decryption
« Reply #2 on: December 08, 2020, 06:20:31 pm »
Interesting. In your scheme, however, you will need to input two long strings, in order to encrypt or decrypt the actual plaintext file. If I read this correctly. The plaintext string1 and this string2. Or perhaps, both strings make up the plaintext?

Another way to do this, create one string, consisting of the plaintext, and then XOR each byte with a pseudo-random byte from the QB64 RANDOMIZE function.

Then, all you have to send to the receiver is the seed used in the encryption step. This has a formal name: "symmetric key stream cipher." Pretty hard to crack, as long as the random number sequence is at least as long as the plaintext.

Or, instead of XORing, another possibility is multiplication in encryption, and division in decryption. But that will create a longer ciphertext than plaintext.

Fun stuff.

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: File encryption / decryption
« Reply #3 on: December 08, 2020, 07:29:28 pm »
Hi bplus
so they are not the same exactly?

DIM string1(16384) AS STRING
DIM string1 AS STRING * 16384
GET or PUT seems to like the array type. 

****
Hi Bert22306

Quote
Interesting. In your scheme, however, you will need to input two long strings, in order to encrypt or decrypt the actual plaintext file. If I read this correctly. The plaintext string1 and this string2. Or perhaps, both strings make up the plaintext?

string2 is the buffer for read from file and write to file.

string1 is the random string. It is shown as all "a" for simplicity

basically the code does:  string2 XOR string1
Quote
Another way to do this, create one string, consisting of the plaintext, and then XOR each byte with a pseudo-random byte from the QB64 RANDOMIZE function.

That is what the code does. string1 is the random string, just have to use the RANDOMIZE function

Quote
Then, all you have to send to the receiver is the seed used in the encryption step. This has a formal name: "symmetric key stream cipher." Pretty hard to crack, as long as the random number sequence is at least as long as the plaintext.

There are various methods. The one I like is the long password system. A long password, say, 512 bytes is hashed and then that is used as the password.  The hash function has to be written correctly to obliterate any repetitions etc in the hash itself.

Quote
Or, instead of XORing, another possibility is multiplication in encryption, and division in decryption. But that will create a longer ciphertext than plaintext.

There are other ways but XOR works just fine if done right.

The code overwrites the plain text file with XORed bytes to create cipher text
and when run again
 the code overwrites the cipher text file with XORed bytes to create plain text
« Last Edit: December 08, 2020, 07:59:56 pm by NOVARSEG »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: File encryption / decryption
« Reply #4 on: December 08, 2020, 07:58:54 pm »
Quote
Hi bplus
so they are not the same exactly?

DIM string1(16384) AS STRING
DIM string1 AS STRING * 16384
GET or PUT seems to like the array type.

I will show a difference:
Code: QB64: [Select]
  1. DIM string1(16384) AS STRING
  2. DIM string2 AS STRING * 16384
  3.  
  4. FOR i = 1 TO 16384
  5.     string1(i) = STR$(i)
  6. ' no error
  7.  
  8. FOR i = 1 TO 16384
  9.     string2(i) = STR$(i)   ' <<<<<<<<<<<<< red lined!!!
  10.  

Here's another:
Code: QB64: [Select]
  1. DIM string1(16384) AS STRING
  2. DIM string2 AS STRING * 16384
  3.  
  4. PRINT LEN(string1(1))
  5. PRINT LEN(string2)
  6.  
  7.  
  8.  
« Last Edit: December 08, 2020, 08:01:03 pm by bplus »

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: File encryption / decryption
« Reply #5 on: December 08, 2020, 08:15:26 pm »
bplus
Interesting
whoop made a mistake i had 2 string1
****

DIM string1(16384) AS STRING
DIM string2 AS STRING * 16384
 
PRINT LEN(string1())
PRINT LEN(string2)

are they the same length?
 
« Last Edit: December 08, 2020, 08:21:46 pm by NOVARSEG »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: File encryption / decryption
« Reply #6 on: December 08, 2020, 08:29:15 pm »
bplus
Interesting
whoop made a mistake i had 2 string1
****

DIM string1(16384) AS STRING
DIM string2 AS STRING * 16384
 
PRINT LEN(string1())
PRINT LEN(string2)

are they the same length?

;-)) well you could run the code but yes! string2 is a fixed length string always it will have length 16384 because that's how you DIM'd it.

String1 is an array of variable length strings we have 16384 of those dimensioned for that array of strings, so at the moment it has a length of 0 because it hasn't been assigned a value yet.

« Last Edit: December 08, 2020, 08:30:40 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: File encryption / decryption
« Reply #7 on: December 08, 2020, 08:49:22 pm »
@NOVARSEG

I just put your code in the IDE, no offense but it's a mess, which tells me you hadn't tried it yourself.

Not good.

Not only should we not try it on important files, we shouldn't try it at all, not safe.
But we couldn't run this one, as is, so there's that ;-))

I suggest trying XOR on 2 strings before moving up to files. It's a nice idea if it works.
« Last Edit: December 08, 2020, 08:53:45 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: File encryption / decryption
« Reply #8 on: December 08, 2020, 09:48:40 pm »
Interesting. In your scheme, however, you will need to input two long strings, in order to encrypt or decrypt the actual plaintext file. If I read this correctly. The plaintext string1 and this string2. Or perhaps, both strings make up the plaintext?

Another way to do this, create one string, consisting of the plaintext, and then XOR each byte with a pseudo-random byte from the QB64 RANDOMIZE function.

Then, all you have to send to the receiver is the seed used in the encryption step. This has a formal name: "symmetric key stream cipher." Pretty hard to crack, as long as the random number sequence is at least as long as the plaintext.

Or, instead of XORing, another possibility is multiplication in encryption, and division in decryption. But that will create a longer ciphertext than plaintext.

Fun stuff.

As Bert said, this isn't that complicated to do.   Here's a quick example of a normal string, encrypted, and then decrypted, using a simple seed and RND with XOR:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(720, 1024, 32)
  2.  
  3. _TITLE "String Encryption"
  4. a$ = "The Ass and the Lapdog.    A Farmer one day came to the stables to see to his beasts of burden: among them was his favourite Ass, that was always well fed and often carried his master.  With the Farmer came his Lapdog, who danced about and licked his hand and frisked about as happy as could be.  The Farmer felt in his pocket, gave the Lapdog some dainty food, and sat down while he gave his orders to his servants.  The Lapdog jumped into his master's lap, and lay there blinking while the Farmer stroked his ears.  The Ass, seeing this, broke loose from his halter and commenced prancing about in imitation of the Lapdog.  The Farmer could not hold his sides with laughter, so the Ass went up to him, and putting his feet upon the Farmer's shoulder attempted to climb into his lap.  The Farmer's servants rushed up with sticks and pitchforks and soon taught the Ass that Clumsy jesting is no joke."
  5.  
  6. RANDOMIZE USING -1973 'a nice random seed
  7. FOR i = 1 TO LEN(a$)
  8.     b$ = b$ + CHR$(ASC(a$, i) XOR INT(RND * 255))
  9. PRINT "-----------------------------------------------------------------------------------------"
  10.  
  11. RANDOMIZE USING -1973 'the same seed as above nice random seed
  12. FOR i = 1 TO LEN(b$)
  13.     c$ = c$ + CHR$(ASC(b$, i) XOR INT(RND * 255))
  14. PRINT "-----------------------------------------------------------------------------------------"

https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: File encryption / decryption
« Reply #9 on: December 08, 2020, 09:57:57 pm »
Personally, an even easier way I find to encrypt things is to just do something really simple with a compressed file:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1024, 720, 32)
  2.  
  3. _TITLE "String Encryption"
  4. a$ = "The Ass and the Lapdog.    A Farmer one day came to the stables to see to his beasts of burden: among them was his favourite Ass, that was always well fed and often carried his master.  With the Farmer came his Lapdog, who danced about and licked his hand and frisked about as happy as could be.  The Farmer felt in his pocket, gave the Lapdog some dainty food, and sat down while he gave his orders to his servants.  The Lapdog jumped into his master's lap, and lay there blinking while the Farmer stroked his ears.  The Ass, seeing this, broke loose from his halter and commenced prancing about in imitation of the Lapdog.  The Farmer could not hold his sides with laughter, so the Ass went up to him, and putting his feet upon the Farmer's shoulder attempted to climb into his lap.  The Farmer's servants rushed up with sticks and pitchforks and soon taught the Ass that Clumsy jesting is no joke."
  5. b$ = _DEFLATE$(a$)
  6. FOR i = LEN(b$) TO 1 STEP -1
  7.     c$ = c$ + MID$(b$, i, 1) 'A simple reverse order of the compressed file, to "encrypt it".
  8. PRINT "--------------------------------"
  9. PRINT "--------------------------------"
  10.  
  11. d$ = _INFLATE$(c$)
  12. PRINT "--------------------------------"
  13. PRINT d$; "Notice this is blank?  It's not a valid compressed file, so it fails on decompression and returns nothing."
  14. FOR i = LEN(c$) TO 1 STEP -1
  15.     e$ = e$ + MID$(c$, i, 1) 'A simple reverse order of the compressed file, to "decrypt it".
  16. f$ = _INFLATE$(e$)
  17. PRINT "--------------------------------"

All I'm doing here is compressing my string, and then reversing it.  That's it, and yet, it'd be hard as heck for anyone to sort out what type of file it is, or what the contents are.  You could NOT each byte, or XOR each byte, or do whatever the heck else you want to do with it, but unless the other person knows the same process, they're not going to have an easy time decoding whatever the contents are.

File encryption/decryption doesn't have to be that hard of a process to implement -- it's just BASIC programming, in the end.  :P
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: File encryption / decryption
« Reply #10 on: December 08, 2020, 11:12:31 pm »
Thanks @SMcNeill

Your simple examples put the kibosh on the effort I was struggling with today. ;-))

Those 2 examples are simple. So that's how to do XOR! Cool.

Offline NOVARSEG

  • Forum Resident
  • Posts: 509
    • View Profile
Re: File encryption / decryption
« Reply #11 on: December 08, 2020, 11:53:35 pm »
Quote
I just put your code in the IDE, no offense but it's a mess, which tells me you hadn't tried it yourself.

Not good.

Not only should we not try it on important files, we shouldn't try it at all, not safe.
But we couldn't run this one, as is, so there's that ;-))

I expected it to have syntax errors but it is essentially correct.
I don't have any IDE at present

One error was
CLOSE 1
it should be CLOSE #1

OK I should try out my own code.

SMcNeill

compression method that works too


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: File encryption / decryption
« Reply #12 on: December 09, 2020, 12:16:42 am »
Quote
I don't have any IDE at present

@NOVARSEG   sorry to read, what's up with that?

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: File encryption / decryption
« Reply #13 on: December 09, 2020, 12:25:03 am »
Here is a peak what the IDE is red-lining, I commented out the first to get to 2nd... and repeat comment 2nd to get 3rd...

The middle section was left clear but I confess I don't understand what it's doing.

Code: QB64: [Select]
  1.  
  2. DIM string1(16384) AS STRING
  3. DIM string2(16384) AS STRING
  4. FPOS = 1
  5. '''''''''' string1 is an array ' string1 = string$(16384,"a") 'string1 could randomized for better security
  6. '''''''''' missing quotes '' OPEN TEST.TXT FOR BINARY AS #1
  7.  
  8. LFILE = LOF(1)
  9.  
  10.     IF LFILE = 0 THEN EXIT DO
  11.  
  12.     IF LFILE < 16384 THEN
  13.         GET #1, , string2(LFILE) 'file read
  14.         FPOS = FPOS + LFILE 'FPOS = file position after GET
  15.         NBYTES = LFILE
  16.         GOSUB XORstring2 'encrypt or decrypt
  17.         SEEK 1, FPOS - LFILE 'adjust file pointer
  18.         PUT #1, , string2(LFILE) 'file write
  19.         LFILE = 0
  20.     END IF
  21.  
  22.     IF LFILE >= 16384 THEN
  23.         GET #1, , string2(16384) 'file read
  24.         FPOS = FPOS + 16384 'FPOS = file position after GET
  25.         NBYTES = 16384
  26.         GOSUB XORstring2 'encrypt or decrypt
  27.         SEEK 1, FPOS - 16384 'adjust file pointer
  28.         PUT #1, , string2(16384) 'file write
  29.         LFILE = LFILE - 16384
  30.     END IF
  31.  
  32.  
  33. XORstring2:
  34. FOR x% = 1 TO NBYTES
  35.     ''''''''''''''string1 is array '''''''''''''''''a$ = MID$(string1),x%,1)
  36.     ''''''''''''' string2 is array '''''''''''''''''b$ = MID$(string2),x%,1)
  37.     ''''''''''''' XOR need numbers '''''''''''''''''b$ xor a$
  38.     ''''''''''''' string2 is array '''''''''''''''''MID$(string2),x%,1) = b$
  39. NEXT x%
  40.  
  41.  
« Last Edit: December 09, 2020, 12:30:33 am by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: File encryption / decryption
« Reply #14 on: December 09, 2020, 01:02:30 am »
Quote
The middle section was left clear but I confess I don't understand what it's doing.

What the middle is an attempt to do, is to read a file in chunks of data of 16384 bytes (though I have no idea why such a number was chosen), XOR those chunks, and then put them back into the file.

OPEN “TEMP.TXT” FOR BINARY AS #1
l = LOF(1)
a$ = SPACE$(l)
GET #1, 1, a$
FOR i = 1 TO l
   b$ = b$ + CHR$(ASC(a$,i) XOR 97)
NEXT
PUT #1, 1, b$
CLOSE

There’s the exact same program, simplified down for usability and understandability.

Since string1 = string$(16384,"a"), it’s nothing more than a repetitive set of “a” characters, which is CHR$(97).  Since XOR works with numbers, I simply hardcoded that XOR 97 above and was done with it.

Read a file into a string.
XOR the contents of the string.
Write the string back to “encrypt” the file.

It’s that simple, unless folks just want to try and complicate things to obfuscate their code/process.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!