# What makes a "good" encryption algorithm?

• July 11th, 2012, 04:39 PM
aesguitar
What makes a "good" encryption algorithm?
I fooled around with a self-made encryption algorithm that uses all printable ASCII characters ([space] to ~). It takes a String and the algorithm shift all the characters by a user prompted amount by a user given amount of times. I'm guessing this randomness of the encryption key and randomness of the amount of encryptions makes it stronger, however, what really makes a good algorithm. Keep it basic, I'm no cryptologist. I also have a decryptor specifically for this algorithm built in.

Here's the actual algorithm:

Code java:

```package algorithms;   import javax.swing.JOptionPane;   public class Encryptor {   private static String[] vals = {" ","!", "\"","#","\$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9" ,":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V" ,"W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","}","|" ,"}","~"}; private static int max = vals.length;   public Encryptor(){}   private static String[] toArray(String enc) { String[] arr = new String[enc.length()]; for(int i = 0; i < enc.length(); i++) { arr[i]=enc.substring(i,i+1); } return arr; }   private static int[] numValues(String[] enc) { int[] numvals = new int[enc.length];   for(int i = 0; i < enc.length;i++) { for(int j = 0; j < max; j++) { if(enc[i].equals(vals[j])) { numvals[i] = j; break; } } }   return numvals; }   //shifts each character by the specified increment public static String hardEncrypt(String enc, int inc, int times) { String fin = ""; int[] nums = numValues(toArray(enc)); for(int amount = 0; amount < times; amount++) { fin = ""; for(int i = 0; i < enc.length(); i++) { int ind = nums[i] + inc; if(ind < 0) { ind *= -1; } if(ind >= max) { while(ind >= max) ind -= max; } fin += vals[ind]; } nums = numValues(toArray(fin)); }   return fin; }   public static String keyDecrypt(String enc, int key, int times) { String fin = ""; int[] nums = numValues(toArray(enc)); for(int amount = 0; amount < times; amount++) { fin = ""; for(int i = 0; i < enc.length(); i++) { int ind = nums[i] - key; if(ind < 0) { ind += max; } if(ind >= max) { while(ind >= max) ind -= max; } fin += vals[ind]; } nums = numValues(toArray(fin)); }   return fin; }   public static String easyEncrypt(String enc) { return hardEncrypt(enc, 3,1); }   public static String decryptEasyEncrypt(String dec) { return hardEncrypt(dec, -3,1); } public static void main(String[] args) { boolean done = false; while(!done) { String toBe = "";   toBe = JOptionPane.showInputDialog("What would you like to be encrypted?");   try{ if(toBe.equals(null)){} }catch(NullPointerException e) { int i = JOptionPane.showConfirmDialog(null, "Are you sure?"); if(i == 0) System.exit(0); else{ toBe = JOptionPane.showInputDialog("What would you like to be encrypted?"); }   }     String owMuch = ""; int howMuch = 0;   owMuch = (JOptionPane.showInputDialog("How much would you like it encrypted? (any number)"));   try{ if(owMuch.equals(null)){} }catch(NullPointerException e) { int i = JOptionPane.showConfirmDialog(null, "Are you sure?"); if(i == 0) System.exit(0); else{ owMuch = (JOptionPane.showInputDialog("How much would you like it encrypted? (any number)")); }   }   try{ howMuch = Integer.parseInt(owMuch); }catch(NumberFormatException e){ JOptionPane.showMessageDialog(null, "Argument must be an integer. Encryption key set to 71."); howMuch = 71; }   String owMany = ""; int howMany = 1; owMany = JOptionPane.showInputDialog("How many times do you want it encrypted? (any number)");   try{ if(owMuch.equals(null)){} }catch(NullPointerException e) { int i = JOptionPane.showConfirmDialog(null, "Are you sure?"); if(i == 0) System.exit(0); else{ owMany = (JOptionPane.showInputDialog("How many times do you want it encrypted? (any number)")); }   }   try{ howMany = Integer.parseInt(owMuch); }catch(NumberFormatException e){ JOptionPane.showMessageDialog(null, "Argument must be an integer. Encryption amount set to 1."); }         long start = System.currentTimeMillis(); String enc = hardEncrypt(toBe, howMuch, howMany); long end = System.currentTimeMillis();   JOptionPane.showMessageDialog(null, "\"" + toBe + "\" encrypted by " + howMuch + ", " + howMany + " times is: \n\n" + enc + "\n\nEncryption took " + (end-start) + "ms.");   int i = JOptionPane.showConfirmDialog(null, "Again?"); if(i != 0) { done = true; }   } } }```

 Redoing a bit of the code. Removed code from post.
• July 11th, 2012, 05:55 PM
pbrockway2
Re: What makes a "good" encryption algorithm?
Quote:

I'm guessing this randomness of the encryption key and randomness of the amount of encryptions makes it stronger, however, what really makes a good algorithm.
I'm not an expert, but I would say the answer is "something that can't easily be reversed".

So how easily can the bad guys reverse your algorithm? It seems to turn on what "easy" means. Easy relative to what? Your algorithm will be good if it costs the bad guys more in computing power and time than what they gain from knowing your secret. In that sense the goodness is not a property of the algorithm alone, but of the context in which it is going to be used.

But - as we all know! - the amount of computing power and time a task takes depends on our intelligence and the quality of our code. So the goodness of the algorithm will depend on the intelligence of the bad guys. If they're smart your algorithm won't be as good as if they're dumb. We ought to assume the bad guys are state-of-the-art smart. Notice that even this assumption doesn't make the goodness of the algorithm a property of the algorithm alone. The state of the art changes all the time: today it is very hard to factorise numbers. So if an algorithm depends on multiplying primes (easy), the bad guys will have to factorise (very hard) to reverse it. But what about tomorrow? If factorising becomes easy because of the development of a new technique the formerly good algorithm will become useless.

-----

Unless I've missed something, the first thing that they'll observe is that the result of shifting things a multiple number of times is equivalent to a single shift. In other words hardEncrypt() could just do a single shift of inc*times and be done. And how many such shifts are possible anyway? They'll notice that there are only values.length such shifts, because there are only that many characters that could be shifted into the first position and the rest follow into place.

So the bad guys try all values.length "reverse shifts" and check the words that result with the contents of a dictionary (which they keep loaded in the computer's memory for just such nefarious purposes). Once they get hit (match on each word), your secret is out :(

How long will it take? A few tens or hundreds of milliseconds, I guess. The longest step is reading your encrypted message.

-----

The small number of different shifts (array.length) was a real help to the bad guys. Perhaps you could try scrambling rather than shifting. That would give you array.length factorial different encryptions which is a *huge* number and should keep the bad guys busy. Being state-of-the-art they'll know that certain letters occur more often than others and will use that to get a start on unscrambling.

And so it goes: every step you take, they make a counter step.
• July 11th, 2012, 06:07 PM
aesguitar
Re: What makes a "good" encryption algorithm?
Alright I see what your saying. It didn't take long to write the decryption method. Say I include a line in the shift that makes each shift seem like a random amount. Like first letter is shift x + 5x, then the next is shifted x + 3x, then x + 2x, then x + x, then x, so on so forth repeating as necessary from a different algorithmic starting point each time. Wouldn't having something like that eliminate several key factors that are present in a simple-substitution encryption?
• July 11th, 2012, 06:14 PM
copeg
Re: What makes a "good" encryption algorithm?
Quote:

what really makes a good algorithm
I'm no expert on the subject, but off the top of my head some of the advantages I'd look for in a good encryption algorithm would be security (is it easy to hack?), efficiency, data type independent, ability to encrypt in a key dependent fashion...

Here's a very simple encryption algorithm that relies on bit swapping: I'd say far from secure but I think a good demonstration. It could be adopted to use a random keys of any bit length, in which you swap only the 'on' bits from the key, making it harder to decrypt. Its fast, and (in theory) is data type independent

Code java:

```public class Encryption{ /** * Encrypts/decrypts the parameter byte array. This simply uses the bitwise complement operator to swap all bits to their complement. * @param bytes * @return */ public static byte[] encrypt(byte[] bytes){ for ( int i = 0; i < bytes.length; i++ ){ bytes[i] = (byte)~bytes[i]; } return bytes; } public static void main(String[] args){ String toEncrypt = "This is a test"; byte[] bytes = toEncrypt.getBytes(); String encrypted = new String(encrypt(bytes)); System.out.println("Encrypted: " + encrypted); System.out.println("Decrypted" + new String(encrypt(bytes))); } }```