This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
billysback's profile picture

Encer - UNIQUE file encrypter

Started by billysback, 14 November 2012 - 07:17 AM
billysback #1
Posted 14 November 2012 - 08:17 AM
Encer

(note the "UNHACKABLE"ness is theoretical, read the very bottom spoiler for an explanation in to why it's unhackable)

Let's get the big question out of the way first: what makes this unique.
This program encrypts files in a way that I believe no human could easily decrypt, but (here's the killer) it does it without the use of any randomness; every "randomly" generated is based upon the password, this means that instead of storing the password somewhere in order to encrypt/un-encrypt the file the file is encrypted/un-encrypted USING the password.

Now you may be thinking "what if I enter the wrong password, does it just un-encrypt it all messed up?", the answer is no. I could tell you why not, but that would be spoiling it :)/>/>, there is a password check, just an encrypted one, and the password it's self is never checked.

At NO point in the encryption process is the password saved ANYWHERE, only the result of it's encryption.

Now lets get on to it's usage, you simply run the program then follow the on-screen instructions (enter file dir, password and whether you are opening or closing (un-encrypting or encrypting) a file

Well, that's it… here's the program:
Spoilerhttp://pastebin.com/PjzXxXSB

Note: you can use any of the following characters in the file you wish to encrypt:

pqowieurytlaksjdhfgmznxbcvPLOKIJUHYGTFRDESWAQMNBVCXZ|./,?><#';[]~@:{}=+-_0)9(8*7&amp;6^5%4$3£21! ¬"
just so you know. (case sensitive)
Any characters in a file will not be unencrypted back to what they were, all characters out of this range will be the same, but what the same is will be dependent on your password (and other factors)

example of encryption before/after:
Spoilerbefore:
Spoiler



£23

Hello my name is billy

this is ENCRYPTED

lalala :P/>/>

"HELLO"

'lol'

¬testing¬

£23

After:
Spoiler

jvhklsPu

atyawehn

BsndztTvhskaKtYvltFdntMvmskajtDvltDdjtTvcscd

mtWvgsKdueIvLskaXt-v[s/dQt|vXs,dCt

TvvsPdntTvvska(t|v

stCdXtvSsQdte

$vcsgdzt$v

atjamtJvLsvdjtBvUssaye

bnuttape



Password?
never your mind!


The super boring maths behind it:
SpoilerThis just explains what the program does with each character when it deciphers it, it might ruin the magic for some.

there is a string, defined as alpha, containing all characters on my QWERTY keyboard (without using alt).
the program first gets the number that the character appears at in the alpha

it then uses the index of the character on it's string to get a "random" letter from the password, by doing index - length of password until index < password

It then gets the character at this index of password and get's IT'S number, this is the modifier.

the random number is the character number added to the modifier ®.

if r is greater than the length of alpha then r is = to r - length of alpha and mod is equal to mod - a random number of pass, using my password encrypted random character generator, if this makes it less than one then you add r, if this makes it equal to what it originally was then you - 1, if it is greater than the length of alpha then it equals the length of alpha - 1.

The program then gets two characters from r and mod and places them in the string.

And that's the boring maths, this is it in code form:

	local i = index
--make the index "valid"
	while i > string.len(pass) do
		i = i - string.len(pass)
	end
--define "mod" using the index
	local mod = getNum(string.sub(pass, i, i))
--define "n" using the character
	local n = getNum(ch)
--define "r" using n + mod
	local r = n + mod
	local omd = mod
	if r > string.len(alpha) then
		r = r - string.len(alpha)
--mod madness!
		omd = mod - getRand(pass)
		while omd < 1 do omd = omd + r end
		if omd == mod then omd = omd - 1 end
		if omd > string.len(alpha) then omd = string.len(alpha)-1 end
	end
--use r and mod to create a double character representing the original character!
	return getCh(r)..getCh(omd)


Why this is theoretically impossible to hack:
Spoileralso, on a side note, without a decoder and the password this is basically impossible to hack, there is a way to get just part of the password but this will not be reliable, this could be just two letters of the password or the whole thing. There is no way to brute force this; there is no string limit so theoretically the possible character combinations that make up the password are infinite. Anything encrypted with this program is, essentially, utterly secure. Unless someone get's hold of your password.

Even someone like me, with complete understanding of the code, could not try and hack someone Else's program because I haven't preset any values to generate the encrypted file with (other than alpha).
KaoS #2
Posted 14 November 2012 - 08:35 AM
interesting technique, you should take a look at the method I used in my encryption program (it's really a cipher). it shows the manual work on the screen as you use it. I like it because you MUST have the keyword to decrypt the password so it is quite cool. here is a link (I know it is an HTA file, it is 100% secure, I do not actually know if HTA files can cause harm to your PC but some people are wary of them)

that was an early version that is not case sensitive and has a few minor bugs that were not ironed out yet. I have the complete one at home and will correct the link ASAP. see if you can work out how the cipher actually works - it is easy to do manually and is actually quite useful (it can actually be done on paper). you can send basic encrypted messages to people with it and as I said. you have to have the keyword
Sammich Lord #3
Posted 14 November 2012 - 08:39 AM
Pretty cool script.
billysback #4
Posted 14 November 2012 - 09:11 AM
interesting technique, you should take a look at the method I used in my encryption program (it's really a cipher). it shows the manual work on the screen as you use it. I like it because you MUST have the keyword to decrypt the password so it is quite cool. here is a link (I know it is an HTA file, it is 100% secure, I do not actually know if HTA files can cause harm to your PC but some people are wary of them)

that was an early version that is not case sensitive and has a few minor bugs that were not ironed out yet. I have the complete one at home and will correct the link ASAP. see if you can work out how the cipher actually works - it is easy to do manually and is actually quite useful (it can actually be done on paper). you can send basic encrypted messages to people with it and as I said. you have to have the keyword
I don't quite get it;
what are the two boxes, they seem to give different output, and for the top box teh four lines underneath seem to be the word followed by a key generated (I presume) using the word, so you can just fill the lines with the word -.-

I doubt you could decrypt mine on paper (you probably could but you would need two pieces of paper and a lot of patience… look forward to counting letters lots of times)
KaoS #5
Posted 14 November 2012 - 09:33 AM
basically the top text box is a keyword used to encrypt/decrypt the phrase in the second box. the keyword CANNOT contain more than one of any letter or symbol though -> this is fixed in the other version I think
pruby #6
Posted 14 November 2012 - 11:54 AM
Umm, you're basically putting the password in your output. Look at every second character.


local enc = ">cyoImaptuuuvehrngKrbaFfdtnhroHm°IujthegrHc"
local password = ""

for i = 2,string.len(enc),2 do
  password = password .. string.sub(enc, i, i)
end

print(password)

You've obfuscated a little, but I think I can guess the password is "computercraft" from that.

Seriously, don't try to invent ciphers. If you want a good cipher you can easily do in CC, try RC4.
KleinRefrigerator #7
Posted 14 November 2012 - 12:29 PM
Not to mention that you don't even use the values of every other character, just whether it's different than the corresponding character in the password. If you really must do it this way, just use two characters, say 1 and 0. It would make a lot more sense to just mod the result by the length of the alphabet, then you'd have a simple polyalphabetic substitution cipher with a rolling key.

If you do that, though, be aware that as with all stream ciphers, if you have two messages encrypted with the same key, you can find out something of the relationship between the two messages. In this case, a difference map that would let you convert one message into the other. Try encrypting two similar messages, you should see that the ciphertext only changes in the positions where the messages are different. You can deal with this by adding a salt, an extra part of the password that's transmitted with the message (or put in the file) that you add to the password before doing the encryption and decryption. That method is still vulnerable to frequency analysis, but it would be nontrivial to break, and might be sufficient for minecraft.

But basically this:
If you want a good cipher you can easily do in CC, try RC4.
KaoS #8
Posted 14 November 2012 - 12:35 PM
don't try to invent ciphers

I'm sorry but I completely and utterly disagree with that

if you are learning and want to try to make something (yes, even if it is the cliché door lock -rolls eyes-) then I say go ahead. the forums aren't flooded with ciphers so it is still a fairly original idea. even if you find this thread of no use whatsoever then just leave it be

TL;DR don't bash the guy for just trying something, he is at least participating
KleinRefrigerator #9
Posted 14 November 2012 - 12:44 PM
don't try to invent ciphers
I'm sorry but I completely and utterly disagree with that

Yes, I agree, and I hope I didn't give that impression. That really should say, "don't try to invent ciphers for sensitive purposes." There's nothing wrong with messing around, even in cryptography, just don't do it if you're, say, securing actual bank transactions or the like.
Cranium #10
Posted 14 November 2012 - 12:51 PM
You want something that is utterly undecipherable, make a program that requires the input of multiple computers to decode.
KleinRefrigerator #11
Posted 14 November 2012 - 12:59 PM
You want something that is utterly undecipherable, make a program that requires the input of multiple computers to decode.
Eh. Perfectly secret encryption is possible if and only if your key is at least as long as your message. The reason for this is that you can (with sufficient processing power) find a key that will decode some ciphertext to absolutely any message of the same length. For an example of this, see one-time pads.

If all you're looking for is a system that cannot practically be broken (the technical term for this is sanity), implement a well studied system like AES. A good cipher should be simple to execute, and requiring several computers really isn't.
Cranium #12
Posted 14 November 2012 - 01:18 PM
I meant undecipherable. Not practical. Besides, using multiple computers would be a pain, and you would never get it deciphered even using it correctly, cause you would run out of patience long before you enter all the right keys.
pruby #13
Posted 14 November 2012 - 01:36 PM
Yes, I agree, and I hope I didn't give that impression. That really should say, "don't try to invent ciphers for sensitive purposes." There's nothing wrong with messing around, even in cryptography, just don't do it if you're, say, securing actual bank transactions or the like.

I'd add "don't post it to a forum with UNHACKABLE in the topic" - it's likely to mislead others who don't know any better. I encourage everyone to program - writing programs teaches you to write better programs. Unfortunately the same is simply not true of ciphers - the only way to write better ciphers is to break others. By all means learn about ciphers, but don't claim they're unbreakable.

http://www.schneier....ml#cipherdesign

P.S. That's nothing about you. I wouldn't make those claims about a cipher I wrote either.
KaoS #14
Posted 14 November 2012 - 01:40 PM
Ok, that is a fair enough claim. I have to agree there :P/>/>
KleinRefrigerator #15
Posted 14 November 2012 - 01:55 PM
I meant undecipherable. Not practical. Besides, using multiple computers would be a pain, and you would never get it deciphered even using it correctly, cause you would run out of patience long before you enter all the right keys.
That's only a benefit if the algorithm is secret. If it's not, one could just as easily run the algorithm with all local sources. The Caesar cipher is only secure if nobody knows how it works. Another property of a good cryptosystem is it's roughly as secure if nobody knows how it works as if everybody does. AES would be much easier to use for the legitimate users and probably harder to break for an attacker, depending on the specifics.

I'd add "don't post it to a forum with UNHACKABLE in the topic" - it's likely to mislead others who don't know any better.
That's a fair objection. I wanted to touch on it a bit more, but I decided to keep my first message more brief. The bottom line is polyalphabetic substitution ciphers like this one can generally be broken by a serious attacker whether you include a slightly obfuscated key in the message or not. (Unless your key is as long as the message or close.) The real question here is how serious the attackers are in Minecraft and whether it would be any less practical to use a more secure system. Still, it's a nice try.
billysback #16
Posted 14 November 2012 - 08:06 PM
Umm, you're basically putting the password in your output. Look at every second character.


local enc = ">cyoImaptuuuvehrngKrbaFfdtnhroHm°IujthegrHc"
local password = ""

for i = 2,string.len(enc),2 do
  password = password .. string.sub(enc, i, i)
end

print(password)

You've obfuscated a little, but I think I can guess the password is "computercraft" from that.

Seriously, don't try to invent ciphers. If you want a good cipher you can easily do in CC, try RC4.
woops…

I just realised an idiot mistake I made:
in my "random" generator, I though I had added a load of math pointlessly, so got rid of it, now I just realised that I was adding the letters of the password back in to the password…

I just updated the key generator so this doesn't happen :P/>/>

( also, I realized that a password encrypted on these forums was bound to get near to no attention, so I decided to add something controversial in to the title so that more people would look at it, thanks :)/>/> for your time; also I'm only 15, This is basically the only cypher I have made and I made a mistake that I didn't spot, it's kinda fixed :/ )
billysback #17
Posted 15 November 2012 - 04:48 AM
Update:
revamped it; It should be much harder to hack now… (random function improved, however unencrypting isn't 100% accurate (it's about 99% and it depends on the password, not really sure why this happens…)
KleinRefrigerator #18
Posted 15 November 2012 - 07:20 AM
Update:
revamped it; It should be much harder to hack now… (random function improved, however unencrypting isn't 100% accurate (it's about 99% and it depends on the password, not really sure why this happens…)

It seems to always fail to decrypt when I use a password containing numbers. I have to say I'm not particularly fond of the fact that it encrypts and decrypts in-place, especially given that it sometimes fails. And I still don't really understand why you're adding an extra byte for every byte of ciphertext.
billysback #19
Posted 15 November 2012 - 08:47 AM
because I needed a way to tell if the first character (the "base" character) has been modified, I tell this using the secondary character…

by "in-place" do you mean you want a secondary out-put file?
KleinRefrigerator #20
Posted 15 November 2012 - 11:48 AM
Right, but generally, polyalphabetic substitution ciphers don't require that. Can't you mod by the length of your alphabet instead? That would probably simplify the algorithm too.
And yes, a different output would be nice.
pruby #21
Posted 16 November 2012 - 12:05 PM
There's a fundamental problem with the two character output. Any given combination of input character and password character produces one unique pair of output characters. This varies with password length, but not in any other way. For any given input character, there are #alpha possible pairs of characters which map to it. Just by generating a table, you can identify the only input character which could produce any given pair, regardless of password content.

Add the following to your code to decrypt any line:

Spoiler

local function pair2pair(passch, ch, passlen)
		local mod = getNum(passch)
		local n = getNum(ch)
		local r = n + mod
	  
		local omd = mod
		if r > string.len(alpha) then
				r = r - string.len(alpha)
				omd = mod - passlen
				while omd < 1 do omd = omd + r end
				if omd == mod then omd = omd - 1 end
				if omd > string.len(alpha) then omd = string.len(alpha)-1 end
				if omd == mod then omd = omd - 1 end
		end
	  
		if omd ~= mod and omd > string.len(alpha) then omd = 1 end
		if omd < 1 and omd ~= mod then omd = string.len(alpha) end
		return getCh(r) .. getCh(omd)
end

function buildMap(passLen)
  local a1
  local a2
  local backMap = {}
  for a1=1,string.len(alpha) do
	local passch = string.sub(alpha, a1, a1)
	for a2=1,string.len(alpha) do
	  local ch = string.sub(alpha, a2, a2)
	  local inputPair = {passch, ch}
	  local resultPair = pair2pair(passch, ch, passLen)
	  backMap[resultPair] = ch
	end
  end

  return backMap
end

local instr = io.read()
local passLen
local idx
for passLen=1,40 do
  local text = ''
  local backMap = buildMap(passLen)
  for idx = 1,string.len(instr),2 do
	local inPair = string.sub(instr, idx, idx+1)
	local ch = backMap[inPair]
	text = text .. ch
  end
  print("If password length is " .. passLen .. " content is " .. text)
end

It doesn't quite perfectly decode, but I can't get the original code to properly decrypt my message either.

Run on "RrhlOfdlAIzjliAgslLrzmcfzlTIxjRsPgxlvrKm" produces:

If password length is 1 content is Ielikeecom"utercraft
If password length is 2 content is Ielikeecom�utercraft
If password length is 3 content is Ielikeec"m�utercraft
If password length is 4 content is Ielikeec�m utercraft
If password length is 5 content is Iel"keec�m!utercraft
If password length is 6 content is I"l�k""c m1ut"rcraft
If password length is 7 content is I�l�k��c!m2"t�rcraft
If password length is 8 content is I�l k��c1m��t�"c"aft

Seem to have some issues with non-text characters, but it gets most of them.
KillaVanilla #22
Posted 16 November 2012 - 12:27 PM
You want something that is utterly undecipherable, make a program that requires the input of multiple computers to decode.

Actually, if you want something that is REALLY undecipherable, use a one-time pad and addition (mod 26).

On-topic: A cipher that doesn't even decrypt properly offers a bit of security, but that is easily broken by any competent human.
pruby #23
Posted 16 November 2012 - 01:26 PM
Actually, if you want something that is REALLY undecipherable, use a one-time pad and addition (mod 26).

Not necessary! I've come up with this guaranteed undecipherable code:

SpoilerAre you sure you want to see this?
SpoilerAre you afraid of spooks breaking down your door?
SpoilerDo you want a cipher that is guaranteed 100% undecipherable?
Spoiler

function encipher(text)
  local i
  local result;
  for i = 1,string.len(text) do
    local byte = string.byte(text, i)
    local encrypted = bit.bxor(byte, byte)
    result = result .. string.char(encrypted)
  end
  return result;
end
KillaVanilla #24
Posted 16 November 2012 - 02:48 PM
Actually, if you want something that is REALLY undecipherable, use a one-time pad and addition (mod 26).

Not necessary! I've come up with this guaranteed undecipherable code:

-snip-

I can't tell if you think that I'm being sarcastic. I wasn't, in any case.
KaoS #25
Posted 19 November 2012 - 11:19 PM
hey again, thought I'd let you know that I changed the link to the correct version I had at home, debugged etc