simple encryption/decryption method

It appears that there’s a character limit… of 734 characters, by my tests. Hmm, who’d have though? :confused: I’ve never tried to pass anything but short strings like passwords to it, so I never got to that point. I’m not sure if that’s a limitation of applescript’s do shell script command, if it’s a limit of the enc function, or if I’m off with one of the flags or parameters. Unlike you, I get the error “error reading input file” when I run it with more than 734 characters. I think that the function is really meant to encrypt files, rather than strings, so if you’re looking to encrypt larger blocks of data you might want to write to a temporary file, then encrypt that. The only other option I can think of with my limited knowledge of using openssl and enc, is to break up any input that is larger than 734 into chunks and encrypt/decrypt them individually. I know, this is ugly, but I don’t know of any other way, sorry. Like I said, if you’re handling that much data that needs to be encrypted, you’re probably handling data in separate files anyways, so it may be simple to just encrypt the whole file and read the resulting encrypted file. Google has lots of miscellaneous examples out there if you search around a bit. Good luck.

j

Thanks, J, I’ll pursue the file idea.

Not sure if it helps, but it’s worth mentioning: do shell script Tech Note

Seems to say there’s lots of space for passing the argument, so it must be the encoding/decoding funtion that has a limit:

Here’s a script that breaks up a document, encodes it, then decodes it. Seems to work on the text docs I’ve tested and it’s fast too (using Jobu’s handlers, but breaking up the doc into 500 byte portions)

set f to choose file
set Blks to (get eof of f) div 500 + 1
set CrypDoc to {}
set Doc to ""
-- encode the Original
repeat with j from 1 to 500 * Blks by 500
	set end of CrypDoc to (eS(quoted form of (read f from j for 500), gK(), "e"))
end repeat
-- decode the Encrypted doc
repeat with P in CrypDoc
	set Doc to Doc & (eS(contents of P, gK(), "d"))
end repeat

-- Jobu's Handlers
to eS(inS, inK, inM)
	return do shell script ("echo " & inS & " | openssl enc -bf -" & inM & " -pass pass:" & (quoted form of inK) & " -salt -a")
end eS

to gK()
	set kL to {"jTiiGHa67567U2FsdGVkX184g", "C3w2235689mNVxw35467JnJMH", "JGdD34hn7n7N6bdFg67H6d54o"}
	return ((characters 8 through 13 of (item 2 of kL)) & (characters 2 through 6 of (item 3 of kL)) & (characters 19 through 23 of (item 1 of kL))) as string
end gK

To use it with UTF-16 you’d have to read the file that way - but I didn’t try it (don’t have a native UTF16 doc). Also given the public airing in this thread, anyone thinking of using this for themselves should think about choosing a different set of characters in the gK() handler than Jobu has - he has 16 characters, but I don’t know if that’s a requirement. [689mNVGdD34VkX18] is the output of gK() as is.

Absolutely. The characters I used are totally random, and I encourage people to come up with their own “kL” list of strings, and it would probably be a good idea to change the ranges of the substrings and the order in which they are extracted and appended to the final key, too. This is meant as a basis for coming up with your own scheme, and it would be absurd to cut and paste this into an application and NOT doing any customization. Granted, you’ll find too many discussions about application security floating around on the web, and all of them arrive at the same point… you can try your best but there will always be someone trying to crack your security. By changing all of the factors in how your key is derived and your data stored, you can effectively modify this example to provide a totally custom, quite secure data storage method.

No, not a requirement, although the longer the key, the better the encryption, if I understand correctly. 16 was a nice round number, but you could use any length of key.

j

And if you really want to obfuscate, try some of the techniques described in this article by jj in unScripted

EDIT: Jan 25, 2008. The link above no longer works – the characters in it give the server fits.

Here’s some more silly applescript “encryption” code. This should really be considered more of a fancy encoding than any kind of encryption, since the security of this is near worthless. :stuck_out_tongue: Nonetheless, it’s interesting to play with.

property pie : {"14", "41", "15", "59", "92", "26", "65", "53", "35", "58", "89", "97", "79", "93", "32", "23", "38", "84", "46", "62", "26", "64", "43", "33", "38", "83", "32", "27", "79", "95", "50", "02", "28", "88", "84", "41", "19", "97", "71", "16", "69", "93", "39", "99", "93", "37", "75", "51", "10", "05", "58", "82", "20", "09", "97", "74", "49", "94", "44", "45", "59", "92", "23", "30", "07", "78", "81", "16", "64", "40", "06", "62", "28", "86", "62", "20", "08", "89", "99", "98", "86", "62", "28", "80", "03", "34", "48", "82", "25", "53", "34", "42", "21", "11", "17", "70", "06", "67", "79", "98", "82", "21", "14", "48", "80", "08", "86", "65", "51", "13", "32", "28", "82", "23", "30", "06", "66", "64", "47", "70", "09", "93", "38", "84", "44", "46", "60", "09", "95", "55", "50", "05", "58", "82", "22", "23", "31", "17", "72", "25", "53", "35", "59", "94", "40", "08", "81", "12", "28", "84", "48", "81", "11", "11", "17", "74", "45", "50", "02", "28", "84", "41", "10", "02", "27", "70", "01", "19", "93", "38", "85", "52", "21", "11", "10", "05", "55", "55", "59", "96", "64", "44", "46", "62", "22", "29", "94", "48", "89", "95", "54", "49", "93", "30", "03", "38", "81", "19", "96", "64", "44", "42", "28", "88", "81", "10", "09", "97", "75", "56", "66", "65", "59", "93", "33", "34", "44", "46", "61", "12", "28", "84", "47", "75", "56", "64", "48", "82", "23", "33", "37", "78", "86", "67", "78", "83", "31", "16", "65", "52", "27", "71", "12", "20", "01", "19", "90", "09", "91", "14", "45", "56", "64", "48", "85", "56", "66", "69", "92", "23", "34", "46", "60", "03", "34", "48", "86", "61", "10", "04", "45", "54", "43", "32", "26", "66", "64", "48", "82", "21", "13", "33", "39", "93", "36", "60", "07", "72", "26", "60", "02", "24", "49", "91", "14", "41", "12", "27", "73", "37", "72", "24", "45", "58", "87", "70", "42", "06", "66", "60", "06", "63", "31", "15", "55", "58", "88", "81", "17", "74", "48", "88", "81", "15", "52", "20", "09", "92", "20", "09", "96", "62", "28", "82", "29", "92", "25", "54", "40", "09", "91", "17", "71", "15", "53", "36", "64", "43", "36", "67", "78", "89", "92", "25", "59", "90", "03", "36", "60", "42", "01", "11", "13", "33", "30", "05", "53", "30", "05", "54", "48", "88", "82", "20", "04", "46", "66", "65", "52", "21", "13", "38", "84", "41", "14", "46", "69", "95", "51", "19", "94", "41", "15", "51", "11", "16", "60", "09", "94", "43", "33", "30", "05", "57", "72", "27", "70", "03", "36", "65", "57", "75", "59", "95", "59", "91", "19", "95", "53", "30", "09", "92", "21", "18", "86", "61", "11", "17", "73", "38", "81", "19", "93", "32", "26", "61", "11", "17", "79", "93", "31", "10", "05", "51", "11", "18", "85", "54", "48", "80", "07", "74", "44", "46", "62", "23", "37", "79", "99", "96", "62", "27", "74", "49", "95", "56", "67", "73", "35", "51", "18", "88", "85", "57", "75", "52", "27", "72", "24", "48", "89", "91", "12", "22", "27", "79", "93", "38", "81", "18", "83", "30", "01", "11", "19", "94", "49", "91", "12", "29", "98", "83", "33", "36", "67", "73", "33", "36", "62", "24", "44", "40", "06", "65", "56", "66", "64", "43", "30", "08", "86", "60", "02", "21", "13", "39", "94", "49", "94", "46", "63", "39", "95", "52", "22", "24", "47", "73", "37", "71", "19", "90", "07", "70", "02", "21", "17", "79", "98", "86", "60", "09", "94", "43", "37", "70", "02", "27", "77", "70", "05", "53", "39", "92", "21", "17", "71", "17", "76", "62", "29", "93", "31", "17", "76", "67", "75", "52", "23", "38", "84", "46", "67", "74", "48", "81", "18", "84", "46", "67", "76", "66", "69", "94", "40", "05", "51", "13", "32", "20", "42", "42", "05", "56", "68", "81", "12", "27", "71", "14", "45", "52", "26", "63", "35", "56", "60", "08", "82", "27", "77", "78", "85", "57", "77", "71", "13", "34", "42", "27", "75", "57", "77", "78", "89", "96", "60", "09", "91", "17", "73", "36", "63", "37", "71", "17", "78", "87", "72", "21", "14", "46", "68", "84", "44", "40", "09", "90", "01", "12", "22", "24", "49", "95", "53", "34", "43", "30", "01", "14", "46", "65", "54", "49", "95", "58", "85", "53", "37", "71", "10", "05", "50", "07", "79", "92", "22", "27", "79", "96", "68", "89", "92", "25", "58", "89", "92", "23", "35", "54", "42", "20", "01", "19", "99", "95", "56", "61", "11", "12", "21", "12", "29", "90", "02", "21", "19", "96", "60", "08", "86", "64", "40", "03", "34", "44", "41", "18", "81", "15", "59", "98", "81", "13", "36", "62", "29", "97", "77", "74", "47", "77", "71", "13", "30", "09", "99", "96", "60", "05", "51", "18", "87", "70", "07", "72", "21", "11", "13", "34", "49", "99", "99", "99", "99", "99", "98", "83", "37", "72", "29", "97", "78", "80", "04", "49", "99", "95", "51", "10", "05", "59", "97", "73", "31", "17", "73", "32", "28", "81", "16", "60", "09", "96", "63", "31", "18", "85", "59", "95", "50", "02", "24", "44", "45", "59", "94", "45", "55", "53", "34", "46", "69", "90", "08", "83", "30", "02", "26", "64", "42", "25", "52", "22", "23", "30", "08", "82", "25", "53", "33", "34", "44", "46", "68", "85", "50", "03", "35", "52", "26", "61", "19", "93", "31", "11", "18", "88", "81", "17", "71", "10", "01", "10", "42", "42", "03", "31", "13", "37", "78", "83", "38", "87", "75", "52", "28", "88", "86", "65", "58", "87", "75", "53", "33", "32", "20", "08", "83", "38", "81", "14", "42", "20", "06", "61", "17", "71", "17", "77", "76", "66", "69", "91", "14", "47", "73", "30", "03"}

on xor(anInt, anotherInt) (*xor by Michael Miller at http://www.esglabs.com/*)
	
	set int1 to anInt as integer
	set int2 to anotherInt as integer
	
	set theResult to 0
	set counter to 0
	
	repeat while ((int1 > 0) or (int2 > 0))
		set rem1 to int1 mod 2
		set rem2 to int2 mod 2
		
		if (rem1 ≠ rem2) then
			set theResult to theResult + 2 ^ counter
		end if
		
		set int1 to int1 div 2
		set int2 to int2 div 2
		set counter to counter + 1
	end repeat
	
	return theResult
end xor

on encrypt(txt, pass)
	set txt to txt as text
	set strl to count of txt
	
	if strl < 128 then
		set padnum to 128 - strl
	else if strl > 128 then
		set padone to (strl div 128) - 1
		set padtwo to padone mod 128
		set padnum to padone * 128 + padtwo
	else
		set padnum to 0
	end if
	
	set counter to 0
	
	repeat while counter < padnum
		set counter to counter + 1
		set txt to txt & (ASCII character 215) as text
	end repeat
	
	set strl to count of txt
	
	set charcodes to {}
	
	repeat with i in txt
		set charcodes to charcodes & (ASCII number i) as list
	end repeat
	
	set xored to {}
	set counter to 0
	
	repeat with charcode in charcodes
		set counter to counter + 1
		set pinum to (item (counter mod 899) of pie) as integer
		set xored to xored & (xor(charcode, pinum))
	end repeat
	
	set encrypted to {}
	set counter to 0
	set passcount to count of (pass as text)
	
	repeat with acode in xored
		set counter to counter + 1
		set currpos to counter mod passcount
		if currpos ≠ 0 then
			set currcode to ASCII number (item (counter mod passcount) of pass)
		else
			set currcode to ASCII number (item -1 of pass)
		end if
		set encrypted to encrypted & (xor(acode, currcode))
	end repeat
	
	set ciphertext to {}
	
	repeat with acode in encrypted
		set ciphertext to ciphertext & (ASCII character acode) as text
	end repeat
	
	return ciphertext
	
end encrypt

on decrypt(ciphertext, pass)
	
	set ciphercode to {}
	repeat with achar in ciphertext
		set ciphercode to ciphercode & (ASCII number achar) as list
	end repeat
	
	set decrypted to {}
	set counter to 0
	set passcount to count of (pass as text)
	
	repeat with acode in ciphercode
		set counter to counter + 1
		set currpos to counter mod passcount
		if currpos ≠ 0 then
			set currcode to ASCII number (item (counter mod passcount) of pass)
		else
			set currcode to ASCII number (item -1 of pass)
		end if
		set decrypted to decrypted & (xor(acode, currcode))
	end repeat
	
	set unpie to {}
	set counter to 0
	
	repeat with charcode in decrypted
		set counter to counter + 1
		set pinum to (item (counter mod 899) of pie) as integer
		set unpie to unpie & (xor(charcode, pinum))
	end repeat
	
	set codes to {}
	
	repeat with i in unpie
		if i as integer ≠ 215 then
			set codes to codes & i
		end if
	end repeat
	
	set decoded to {}
	repeat with i in codes
		set decoded to decoded & (ASCII character i) as text
	end repeat
	
	return decoded
end decrypt

encrypt("My name is Ãœmberto, but you can call me Bert :)", "this_is_a_really_boring_password")

(*"78F&bWJ+ÇCS)
Yml[8^/]&H[Q.FQQ6leQofg'rsùÇ∞ǘ™∞”¬Ã±Ã‹Ã âõ°â‰¤â‰ §Ã’Ô¥»Ã±¢âˆ‚™fiõ¶Ã¦šÃ¿Ãƒï¬Ã£§Ä±Î©ÃµÃ„⁄æÉÜéµâ‰¥¥Ä±¢¸Ã’∆⁄´â„¢âˆÃŠÃ„ÛÛÖ∂õ≤--⁄¢¶£¸Ë˜Ã¼Å’ÆÎÇåñô∫"*)

decrypt("78F&bWJ+ÇCS)
Yml[8^/]&H[Q.FQQ6leQofg'rsùÇ∞ǘ™∞”¬Ã±Ã‹Ã âõ°â‰¤â‰ §Ã’Ô¥»Ã±¢âˆ‚™fiõ¶Ã¦šÃ¿Ãƒï¬Ã£§Ä±Î©ÃµÃ„⁄æÉÜéµâ‰¥¥Ä±¢¸Ã’∆⁄´â„¢âˆÃŠÃ„ÛÛÖ∂õ≤⁄¢¶£¸Ë˜Ã¼Å’ÆÎÇåñô∫", "this_is_a_really_boring_password")

(*"My name is Ãœmberto, but you can call me Bert :)"*)

If you have ASCII character 215 in your message, say goodbye to it, because it will disappear in the decrypted result :stuck_out_tongue:

As has been said before, for real encryption, use the OpenSSL library your system was blessed with (if you’re using OS X). If you have mac classic, use pgp or install macperl and use perl encryption modules.

:Edited to add:Okay, So I was wrong about the last part - turns out that “Blowfish and RC5 algorithms use a 128 bit key.” according to the openssl man page. So, you would have to use a different implementation to take advantage of the full keysize. In the meantime, I recommend AES-256, because, hey, it’s good enough for “top secret” information; it ought to be good enough for anyone else, too. :wink:

If you want simple and fast text obfuscation you can use my Scripting Addition MacPack Toolbox. It has a text (ASCII) bi-directinal scramble verb.

Hello everyone. I apologize for bringing the level of discussion down a little, but how would I apply Jabu’s script (or any other script, the simpler the better) to encrypt/decrypt a password I have stored in a shell script. For example, I have a .sh doc which when run, uploads a file to a remote FTP server. Unfortunatly, that means I have to supply the username and password to the FTP within that docuent. Would it be possible to encrypt the password within that .sh file, then have the .sh script call to either the Applescript above or another .sh script in order for the original FTP script to decrypt the password and use it? That may be a little unclear.

What I am wondering is:

How would I encrypt a password within an FTP .sh script, so anyone looking at the password would see the encryption, but the .sh script could decrypt it and use it to carry out the FTP transfer.

Thanks in advance.

The problem with trying to encrypt your shell script is that to encrypt something you need to supply a password for the encryption, so no matter what you need a password and therefore you can’t fully automate the shell script process.

You could use applescript to run your ftp commands. In applescript you can display a dilaog box asking for the password and then insert that into the ftp command. That way you wouldn’t need to have your password in the script itself. Here’s some code to get a password from a script. Note: if your not using OSX 10.4 then remove the “with hidden answer” part. It only works in 10.4 or above.

display dialog "Enter your FTP password" default answer "" with hidden answer
set thePassword to text returned of the result

U2FsdGVkX1/hxPfCffKoZ771jn9B6zHwWWXxtmiY6pNbucQrsdQnwffFwIZ8UZ4y

Hi Adam and Jobu:

A question if I may:

As I run the applescript that handles the text strings longer than 700+ characters, the script asks for the input text file, then runs and nothing else happens, no output, and the script seems to quit by itself… Any ideas?

I’m using Mac OS X 10.5 if that matters.

Thanks in advance amigos,

Migs

Model: MacBook Pro
AppleScript: 1.1
Browser: Firefox 2.0.0.11
Operating System: Mac OS X (10.5)

Migs,

There is a known issue when handling strings longer than 734 characters. As far as I know there’s nothing you can do about this. If you’re handling text larger than this you should probably be working with a document-based setup, which will allow you to use openssl on the entire file rather than on text strings. Look at the openssl manpage for more information. Adam came up with a modification here that breaks up longer strings which you could try too.

Hi, here is simple yet cool encryptor that I came up with a year ago…

set final_decrypt to ""
set final_string to ""
set defualtbutton to "Encrypt"
set return1 to 0
display dialog "eText
Encrypting text since 2008

Copyright © 2008 NanoTech Software Inc." with title "eText" buttons {"Quit", "Continue"} default button 2 cancel button 1 with icon 1
repeat
	set return1 to 0
	display dialog "Enter a string:" default answer final_string & "












" buttons {"Decrypt", "Cancel", "Encrypt"} default button defualtbutton with icon 1 cancel button 2 with title "eText"
	if button returned of the result is "Encrypt" then
		set inputtxt to the text returned of the result
		if inputtxt is "" then
			display alert "Error: Invalid Text" message "You have not entered any text in the text field" buttons {"Quit", "Continue"} default button 2 cancel button 1
			set final_string to ""
		end if
		if inputtxt is not "" then
			try
				set defualtbutton to "Decrypt"
				set countofrepeat to 1
				set countch1 to count characters of inputtxt
				
				
				
				set string1 to ""
				set string2 to ""
				set string3 to ""
				repeat 6 times
					set letter1 to (ASCII character (random number from 33 to 150))
					set string1 to string1 & letter1
				end repeat
				
				repeat 6 times
					set letter1 to (ASCII character (random number from 33 to 150))
					set string2 to string2 & letter1
				end repeat
				
				repeat 6 times
					set letter1 to (ASCII character (random number from 33 to 150))
					set string3 to string3 & letter1
				end repeat
				
				set string4 to ""
				set asciich1 to ""
				repeat countch1 times
					
					set letter1 to character countofrepeat of inputtxt
					set letter2 to ASCII number letter1
					set number1 to random number from 10 to 20
					set letter2 to letter2 + number1
					if number1 = 10 then
						set number1 to "A"
					end if
					if number1 = 11 then
						set number1 to "b"
					end if
					if number1 = 12 then
						set number1 to "C"
					end if
					if number1 = 13 then
						set number1 to "Ã¥"
					end if
					if number1 = 14 then
						set number1 to "E"
					end if
					if number1 = 15 then
						set number1 to "f"
					end if
					if number1 = 16 then
						set number1 to "}"
					end if
					if number1 = 17 then
						set number1 to "h"
					end if
					if number1 = 18 then
						set number1 to "ø"
					end if
					if number1 = 19 then
						set number1 to "j"
					end if
					if number1 = 20 then
						set number1 to "K"
					end if
					set letter2 to ASCII character letter2
					set string4 to string4 & number1
					set asciich1 to asciich1 & letter2
					set countofrepeat to countofrepeat + 1
					set letter1 to ""
					set letter2 to ""
					set number1 to ""
					
				end repeat
			on error error_message
				display alert "Error: Unexpected Error" message "The algorithm that you are using has encountered an unexpected problem." buttons {"Quit", "Continue"} default button 2 cancel button 1
				set final_string to ""
			end try
			set string5 to asciich1
			
			set final_string to string1 & string5 & string2 & string4 & string3
		end if
	else if button returned of the result is "Decrypt" then
		set input_String to the text returned of the result
		if input_String is "" then
			display alert "Error: Invalid Text" message "You have not entered any text in the text field" buttons {"Quit", "Continue"} default button 2 cancel button 1
			set final_string to ""
		end if
		if input_String contains "
" then
			set return1 to 1
			set AppleScript's text item delimiters to "
"
			set input_String to first text item of input_String
			set return1 to 1
		end if
		
		if input_String does not contain "
" then
			set return1 to 1
		end if
		if input_String is not "" then
			if return1 = 1 then
				try
					
					set defualtbutton to "Encrypt"
					set count1 to count of characters of input_String
					set repeatcount1b to 1
					set count1 to count1 - 18
					set count1 to count1 / 2
					set key1 to count1
					set key2 to 6 + count1 + 6 + 1
					set key3 to key2 + count1
					set key1 to characters key2 through key3 of input_String as list
					set final_key to ""
					repeat count1 times
						set number1 to item repeatcount1b of key1
						if number1 is "A" then
							set number1 to 10
						end if
						if number1 is "b" then
							set number1 to 11
						end if
						if number1 is "C" then
							set number1 to 12
						end if
						if number1 is "Ã¥" then
							set number1 to 13
						end if
						if number1 is "E" then
							set number1 to 14
						end if
						if number1 is "f" then
							set number1 to 15
						end if
						if number1 is "}" then
							set number1 to 16
						end if
						if number1 is "h" then
							set number1 to 17
						end if
						if number1 is "ø" then
							set number1 to 18
						end if
						if number1 is "j" then
							set number1 to 19
						end if
						if number1 is "K" then
							set number1 to 20
						end if
						set item repeatcount1b of key1 to number1
						set repeatcount1b to repeatcount1b + 1
					end repeat
					set count2 to count1 + 6
					set decrypt1 to characters 7 through count2 of input_String as list
					set countrepeat1a to 1
					set final_string to ""
					repeat count1 times
						set letter1 to item countrepeat1a of decrypt1
						set number1 to item countrepeat1a of key1
						set letter1 to ASCII number letter1
						set letter1 to letter1 - number1
						set letter1 to ASCII character letter1
						set final_string to final_string & letter1
						set countrepeat1a to countrepeat1a + 1
					end repeat
				on error error_message
					display alert "Error: Invalid Text" message "The text that you have entered to decrypt was not encrypted with this algorithm." buttons {"Quit", "Continue"} default button 2 cancel button 1
					set final_string to ""
				end try
			end if
		end if
	end if
end repeat