|
Post by sarossell on Jan 23, 2020 2:19:52 GMT -5
The definition of a "perfect cipher" is an encryption method that uses a cipher key that is the same size as the data sample being encrypted. This can be easily achieved by simply sampling the text of a known source like the words from a book starting at a predetermined location. This is still not quite perfect though if the source of the key is known.
With Liberty BASIC, we can use the Randomize seed function to create our own "book" of random data to use as the key. The Randomize command makes the random number generator start at the same place and produce the same exact values every time you run it. The trick is knowing what seed was used. The Randomize command requires a decimal value between 0 and 1. That could be anything like .3 or .8675309. To make it easier to remember, you can use a hash function to turn any string of any length into a number that is sufficiently large and random.
In this short program, I use the CSC-32 hash function from the NTDLL to convert any string into a long decimal value to be used as the encryption key. The key is used as the Randomize seed value and then each byte of the input file is XOR'd with a different random byte. All the user has to remember is the original string used. The cool thing about the XOR function is that whatever you XOR together, when you do it again, it simply removes it.
To safely pass an encrypted file to someone else or remind yourself later, you can pass on a clue instead of the actual key string. I like to use the clue of a well known leading actor from a popular movie, but then require the key to be their real name. So, all I have to remember is "True Grit", but then enter John Wayne's real name; Marion Robert Morrison. You could use any other sufficiently obscure strings or clues as you like.
Hope you enjoy it!
-Scott :@)
[Information]
' NAME: XED.bas ' ' DESCRIPTION: Perfect XOR Cipher En/Decryption program. ' ' PROGRAMMER: Scott A. Rossell ' ' DATE: 20.01.23 ' ' VERSION: 0.0.1 ' ' NOTES: [1] Set random seed based on accepted methodology. The trick is ' to use an easily remembered method to refer to a sequence of ' random numbers that are the same number of bytes as the file ' being encrypted, which is impossible to remember, but that can ' be easily reproduced. ' ' [2] Files are expected to have file extensions of exactly three ' characters. ' ' [3] Recommended for small files only.
nomainwin v.Path$ = "C:\*.*"
[Main_Program]
notice "XED v.0.0.1 - Open file." + chr$(13) + "Select a file to be En/Decrypted." filedialog "Open file", v.Path$ , v.InFile$ if v.InFile$ = "" then goto [Quit] else open v.InFile$ for binary as #InFile end if prompt "XED v.0.0.1 - Enter key." + chr$(13) + "Enter the cipher key."; v.Name$ if v.Name$ = "" then goto [Quit] end if randomize(f.SeedCode(v.Name$)) if right$(v.InFile$,4) = ".XED" then v.OrigExt$ = left$(right$(v.InFile$,8),4) v.OutFile$ = left$(v.InFile$,len(v.InFile$) - 8) + " (original) "+ v.OrigExt$ v.Proc$ = "De" else v.OutFile$ = v.InFile$ + ".XED" v.Proc$ = "En" end if open v.OutFile$ for binary as #OutFile for v.Cnt1 = 1 to lof(#InFile) v.Xed$ = chr$(asc(input$(#InFile,1)) XOR int(rnd(1)*256)) #OutFile, v.Xed$; next close #InFile close #OutFile v.Msg$ = v.Proc$ + "cryption Complete." + chr$(13) + chr$(13) + "Exit Program?" confirm v.Msg$; v.GoNoGo$ if v.GoNoGo$ = "yes" then goto [Quit] else goto [Main_Program] end if
[Quit]
run "tskill /a liberty", hide end
[Functions]
function f.SeedCode(in.STG$) ' Uses the DLL to generate a CSC-32 hash of the input string. v.StringLen = len(in.STG$) open "ntdll.dll" for dll as #ntdll calldll #ntdll, "RtlComputeCrc32", 0 as long, in.STG$ as ptr, v.StringLen as long, result as long close #ntdll ' CSC-32 hash is turned into a decimal value. f.SeedCode = val("." + str$(abs(result))) end function
|
|
Tasp
Full Member
Posts: 215
|
Post by Tasp on Feb 1, 2020 14:54:50 GMT -5
Great implementation, I'm not sure how "uncrackable" it is, definately beyond me!
I'm not sure I'd use TSKILL though. And it throws an error for me.
|
|
|
Post by sarossell on Feb 1, 2020 20:55:12 GMT -5
The error "might" be permissions oriented. I've used it without trouble with XP and 10, but I run as Admin by default.
|
|
Sver
Full Member
Posts: 145
|
Post by Sver on Feb 8, 2020 12:50:24 GMT -5
A little bit changed,
'nomainwin
filedialog "Open file", "C:\*.*" , filename$ if filename$ = "" then goto [Quit]
prompt "Password."; password$ if password$ = "" then goto [Quit] randomize(f.SeedCode(password$))
gosub [encrypt] 'gosub [decrypt] end
'------------------------------------------------------------------------------------- [decrypt] open filename$ for binary as #InFile open filename$ for binary as #OutFile
for Cnt1 = 1 to lof(#InFile) v.Xed$ = chr$(asc(input$(#InFile,1)) XOR int(rnd(1)*256)) tot$=tot$+v.Xed$ next Cnt1 '----------------------------------------------- if right$(tot$,5)<>"check" then goto [wrong] end if
u=len(tot$) 'delete word: check tot$= left$(tot$,u-5)
close #OutFile close #InFile '-----------------------------
open filename$ for output as #1 print #1, tot$ close #1 print "Good, Decrypted" return '------------------------------------------------------------------------------------ [wrong] close #OutFile close #InFile print "Wrong" return '------------------------------------------------------------------------------------
'---------------------------------------------------------------------------------- [encrypt] open filename$ for binary as #InFile open filename$ for binary as #OutFile 'add word, check SEEK #InFile, lof(#InFile)
print #InFile, "c" print #InFile, "h" print #InFile, "e" print #InFile, "c" print #InFile, "k" close #InFile
open filename$ for binary as #InFile2
for Cnt1 = 1 to lof(#InFile2) v.Xed$ = chr$(asc(input$(#InFile2,1)) XOR int(rnd(1)*256)) tot$=tot$+v.Xed$ next Cnt1 print "Encrypted" print #OutFile, tot$
close #OutFile close #InFile2 return '-------------------------------------------------------------------------------------------------
[Quit] ' run "tskill /a liberty", hide end '-------------------------------------------------------------------------------------------------------------------------------------------------- [Functions] function f.SeedCode(in.STG$) ' Uses the DLL to generate a CSC-32 hash of the input string. v.StringLen = len(in.STG$) open "ntdll.dll" for dll as #ntdll calldll #ntdll, "RtlComputeCrc32", 0 as long, in.STG$ as ptr, v.StringLen as long, result as long close #ntdll ' CSC-32 hash is turned into a decimal value. f.SeedCode = val("." + str$(abs(result))) end function
|
|
|
Post by sarossell on Feb 8, 2020 14:53:56 GMT -5
Unfortunately, by adding the word "check" you have completely eliminated the effectiveness of the encryption. This is exactly what caused the failure of the German Enigma encryption system in World War II. The hubris of the "Master Race" insisted on ending every message with the phrase "Heil Hitler". Once this was identified and decoded, every message was easily decrypted once the phrase was matched.
:@)
|
|
Sver
Full Member
Posts: 145
|
Post by Sver on Feb 8, 2020 15:29:36 GMT -5
The next password don,t have to be the same. Example the first word of the text is the new password for the next massage of something else.
|
|
|
Post by sarossell on Feb 8, 2020 15:45:35 GMT -5
The program already has a password key procedure. The point of such a system is to make sure you DON'T include the key. Doing so compromises either the current message or subsequent ones. The same goes for steganographic methods. The message is hidden in an image in a way that only the sender and receiver know about. If they included the method with the image, it would compromise the hidden message.
If I may ask, what benefit are you attempting to achieve by adding this second password?
|
|
|
Post by Chris Iverson on Feb 8, 2020 15:46:21 GMT -5
The next password don,t have to be the same. Example the first word of the text is the new password for the next massage of something else. You're misunderstanding. He's not talking about the key. He's talking about the plaintext. What you're encrypting. If someone knows that your plaintext ALWAYS starts with "check:", then that gives them a HUGE advantage when trying to crack it. Of course, that still wouldn't help too much against a one-time pad cipher, but if what gets revealed leads to a hint as to what random key was used to generate the OTP(which it can in this case, since LB's built-in random function isn't crytpographically secure), then they may be able to deduce enough of the pattern that they can generate the rest of the OTP. If I may ask, what benefit are you attempting to achieve by adding this second password? I think he's trying to make sure that what comes out actually got decrypted properly, and wasn't corrupted. Using a static bit of random text isn't a good sign to check for that, though. What I would do in this case is make a hash of all the data you're encrypting, and add that hash to the data being encrypted. The decrypting side then chops off the hash value, hashes the decrypted data again, and compares it to the included hash.
|
|
Sver
Full Member
Posts: 145
|
Post by Sver on Feb 8, 2020 15:47:51 GMT -5
Three times wrong, close program or overwrite file and delete it. It's dependend how they/you Will use it.
Communication between more people or when somebody found your file and or/and your usb-stick.
|
|
|
Post by sarossell on Feb 8, 2020 16:41:52 GMT -5
Sver: Number of times tried is irrelevant. The cracker could easily just copy the data and retry multiple times with each copy. Apologies, I didn't quite understand your second statement. @chris: Agreed, if anything must be added, a full content hash would be a much better choice. As for decrypting the added plain text, it's not easy, but once you find a chunk of consecutive XOR values, it's just a matter of time before you can find the sequence of pseudo random bytes that were originally calculated. After all, a seeded random function is essentially just a list of numbers starting from a random place in a long list of random numbers that never changes - as long as the same seed is used.
|
|
Sver
Full Member
Posts: 145
|
Post by Sver on Feb 8, 2020 16:42:51 GMT -5
Sarossell,
When the owner types a wrong character in the first code when typing the password, it Will encryped again. It is encryped twice. But what was the wrong password? He has only one chance.
|
|
|
Post by Chris Iverson on Feb 8, 2020 16:53:31 GMT -5
But that doesn't prevent him from making a copy of the encrypted data before attempting decryption, which is what he said.
Yes, if I run that decryption algorithm on encrypted data with an incorrect password, it will corrupt the data.
But if I've made a copy of the encrypted data first, I can just throw out the corrupted data and try again.
Also, it's an XOR cipher. Running the encryption again will undo what was done. That's how it works. If you get the password wrong, you don't even have to copy the data and try again. You can just re-run the algorithm with the same password to get the uncorrupted data back.
|
|
|
Post by sarossell on Feb 8, 2020 18:06:10 GMT -5
Sver: Commendable effort with the re-code. I apologize if I came across a bit "teacher-y". I've been working with mathematics and encryption for over thirty years. Please continue to share your ideas and code. There isn't a single person here that couldn't learn something new. And this forum is all about helping and learning to use Liberty BASIC, 'cuz it's such a wonderful tool.
|
|
Sver
Full Member
Posts: 145
|
Post by Sver on Feb 9, 2020 13:47:16 GMT -5
A challenge:
I' ll upload a encrypted word ,doxc with one line text and next weekend you Will give me the decryped text, (encrypted with the second code and i will change the 5 letter word "check" into a other 5 letter word.
When it loose it's security by changing the code, it must be possible.
The first code is very Nice, but it isn't userfriendly.
|
|
|
Post by sarossell on Feb 9, 2020 14:51:46 GMT -5
Let me be clear, while adding the "check" plain text undeniably compromises the encryption, the XOR cipher method is intentionally and GALACTICALLY impossible to crack to begin with. Putting a cat door on a castle on the planet Neptune and then challenging a fat man to walk there and break in is just ignorant. Yes, technically, with ample computing time and money, it can be done, but it's a waste of resources and effort to test. This is a mental exercise in semantics at best.
My point was that THEORETICALLY, adding the plain text compromises the integrity of the cipher BY DEFINITION. In practice however, an equal-size key, pseudo-random, XOR cipher is again, by definition, the "perfect" cipher. If you want to add to it, knock yourself out. In the real world, it won't make the slightest bit of difference.
Now, as this discussion has strayed from the subject of Liberty BASIC, I'd like to return the thread to the subject of interest and ask what changes you might suggest to make the code more "userfriendly"?
:@)
|
|