Protect plain string from decompilers

  • (2 Pages)
  • +
  • 1
  • 2

19 Replies - 6569 Views - Last Post: 11 January 2011 - 10:32 PM Rate Topic: -----

#1 pmiller624  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 55
  • Joined: 02-May 10

Protect plain string from decompilers

Posted 03 January 2011 - 05:21 PM

I have a java application that constantly communicates with my website. I want to protect the address of the site along with other strings from decompilers. My application is obfuscated using proGuard, when it's decompilers every thing looks good except strings are wide open and easy to read.

Anything I can do?

Thanks
Is This A Good Question/Topic? 0
  • +

Replies To: Protect plain string from decompilers

#2 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10660
  • View blog
  • Posts: 39,577
  • Joined: 27-December 08

Re: Protect plain string from decompilers

Posted 03 January 2011 - 05:25 PM

You could use an intermediary application to feed your program the Strings. You could use something like a Servlet, or write your own server application using the java.net package.
Was This Post Helpful? 1
  • +
  • -

#3 pmiller624  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 55
  • Joined: 02-May 10

Re: Protect plain string from decompilers

Posted 03 January 2011 - 07:47 PM

Thank you for your response, could you please explain the intermediary application and how I could use one.
Was This Post Helpful? 0
  • +
  • -

#4 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2777
  • View blog
  • Posts: 11,758
  • Joined: 20-September 08

Re: Protect plain string from decompilers

Posted 04 January 2011 - 07:27 AM

You'll get better obfuscation by defining your String types as char[]
Was This Post Helpful? 1
  • +
  • -

#5 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8342
  • View blog
  • Posts: 31,880
  • Joined: 06-March 08

Re: Protect plain string from decompilers

Posted 04 January 2011 - 12:05 PM

Or even as an array of int[] from which you can build a String later on
You can even hide it into the serialVersionUID of a few of your classes :) (My trick)
Was This Post Helpful? 4
  • +
  • -

#6 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8342
  • View blog
  • Posts: 31,880
  • Joined: 06-March 08

Re: Protect plain string from decompilers

Posted 04 January 2011 - 10:12 PM

View Postpbl, on 04 January 2011 - 01:05 PM, said:

Or even as an array of int[] from which you can build a String later on
You can even hide it into the serialVersionUID of a few of your classes :) (My trick)

three +1 :) You liked it folks ?

Translate ASCII string into decimal String (using 3 digits)
use that String as serialVersionUID
hidden far somewhere translating with % 100 and / 100 the serialVersionUID as a String

Worked for me for years :^: but now my trick is published. Anyhow, I always produce Open source code anymore, the easiest way

This post has been edited by pbl: 04 January 2011 - 10:47 PM
Reason for edit:: post passed from 2 + 1 to 3 +1 should have copyright that trick

Was This Post Helpful? 3
  • +
  • -

#7 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2777
  • View blog
  • Posts: 11,758
  • Joined: 20-September 08

Re: Protect plain string from decompilers

Posted 05 January 2011 - 12:52 AM

Hiding stuff in the serialVersionUID would of course only work for short strings - there's no way you're going to get the url the OP is likely to want to use in there ;)
Was This Post Helpful? 0
  • +
  • -

#8 cfoley  Icon User is online

  • Cabbage
  • member icon

Reputation: 2045
  • View blog
  • Posts: 4,233
  • Joined: 11-December 07

Re: Protect plain string from decompilers

Posted 05 January 2011 - 11:23 AM

True, but any class you write can have a serialVersionUID. I really like that pbl!
Was This Post Helpful? 0
  • +
  • -

#9 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8342
  • View blog
  • Posts: 31,880
  • Joined: 06-March 08

Re: Protect plain string from decompilers

Posted 05 January 2011 - 03:48 PM

View Postg00se, on 05 January 2011 - 01:52 AM, said:

Hiding stuff in the serialVersionUID would of course only work for short strings - there's no way you're going to get the url the OP is likely to want to use in there ;)

So split the String into 10 differents classes and just merge their serailVersionUID when it is time to process :)
Was This Post Helpful? 0
  • +
  • -

#10 37Liion  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 49
  • Joined: 18-February 10

Re: Protect plain string from decompilers

Posted 06 January 2011 - 01:24 PM

Not to criticize, but if somebody really wanted to find out where you're app was connecting to, wouldn't they would monitor the traffic, not decompile your code?

I'm just curious as to how useful this would be in the long run. What situations would make a string this valuable?
Was This Post Helpful? 0
  • +
  • -

#11 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2777
  • View blog
  • Posts: 11,758
  • Joined: 20-September 08

Re: Protect plain string from decompilers

Posted 06 January 2011 - 01:27 PM

Quote

I'm just curious as to how useful this would be in the long run.


In the long run, 'security by obscurity' fails. In the short term, it will help to put off those who are technically unknowledgeable/undetermined
Was This Post Helpful? 0
  • +
  • -

#12 pmiller624  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 55
  • Joined: 02-May 10

Re: Protect plain string from decompilers

Posted 07 January 2011 - 10:16 AM

Thanks all for your replies. While I know that if someone really wants to knew where connections are being made they can easily find out. My plan is to put into place as many systems as possible to make their life hard.

I have taken a hybrid of a lot of your suggestions and also took it one step further with dynamically changing urls. I have also beefed up the security on those pages, so that even if they were found chances are they wouldn't work.

Thanks again
Was This Post Helpful? 0
  • +
  • -

#13 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8342
  • View blog
  • Posts: 31,880
  • Joined: 06-March 08

Re: Protect plain string from decompilers

Posted 10 January 2011 - 05:16 PM

Yesterday I was in a remote place without Interner access
rather then wasting my times, I wrote this GUI to generate the code to hide a String in a serialVersionUID
No license required, just cut & paste
and g00se it will use as many classes as required

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;

/*
 * An application to generate the serialVersionUIDs to encrypt a String in SerialVersionUID
 * Generate also the method code to rebuild it
 */
public class UIDHidder extends JPanel {
	
	private static final long serialVersionUID = 0x1L;
	
	// the number of characters that fit in a long is 8 but to avoid sign problem (when the first one
	// is > 127) we'll store 7 characters in every long
	private static final int NB_CHAR = 7; 

	// to receive the String to encrypt
	private JTextField txtField;
	// to display the code to cut & paste
	private JTextArea codeText;
	// to display the list of the UID
	private MyTable table;
	private MyModel tableModel;
	private JPanel uidPanel;
	// the UID themselves
	private long[] uid;
	// the JLabel to display translation back
	private JLabel labelBack;
	
	UIDHidder() {
		super(new BorderLayout());
		// init uid length to 0
		uid = new long[0];
		
		// the NORTH region where user input text to encrypt
		buildNorth();
		// the CENTER region region contains 2 ScrollPane
		// one with the serailVersionUID the second one with the code to decypher the String
		buildCenter();
		// the JLabel to display back the translated screen
		labelBack = new JLabel("Translated back:");
		labelBack.setForeground(Color.BLUE);
		add(labelBack, BorderLayout.SOUTH);
	}
	
	/*
	 * Build the NORTH region 
	 */
	private void buildNorth() {
		// the NORTH region contains a JTextField with the String to encrypt
		// make a GridLayout(3,1) to put with a blank label in 1st and 3rd row
		// (so won't touch the border)
		JPanel north = new JPanel(new GridLayout(3, 1));
		// first row empty
		north.add(new JLabel(" "));
		// a Box for the center with the JLabel and the JTextField for user input
		Box center = Box.createHorizontalBox();
		JLabel label = new JLabel("  String to encrypt:  ");
		label.setForeground(Color.BLUE);
		center.add(label);
		// where the use input the String to encrypt
		txtField = new JTextField(40);
		txtField.getDocument().addDocumentListener(new EncryptListener());
		center.add(txtField);
		center.add(new JLabel("     "));				// not to touch right border
		// add the Box in the center (middle of the GridLayout)
		north.add(center);
		// 3rd row empty
		north.add(new JLabel(" "));
		add(north, BorderLayout.NORTH);				
	}

	// build the center region
	private void buildCenter() {
		// the CENTER region region contains 2 ScrollPane
		// one with the serailVersionUID the second one with the code to decypher the String
		JPanel centerPanel = new JPanel(new GridLayout(2,1));
		// the top part a JTable in it's scrollpane
		tableModel = new MyModel();
		table = new MyTable(tableModel);
		uidPanel = new JPanel(new BorderLayout());
		uidPanel.add(new JScrollPane(table), BorderLayout.CENTER);
		// just for the JTable to show it's bottom border and to add a margin both sides
		uidPanel.add(new JLabel(" "), BorderLayout.SOUTH);
		uidPanel.add(new JLabel("   "), BorderLayout.WEST);
		uidPanel.add(new JLabel("   "), BorderLayout.EAST);
		centerPanel.add(uidPanel);
		// the bottom part with the TextArea showing the code
		codeText = new JTextArea();
		centerPanel.add(new JScrollPane(codeText));
		add(centerPanel, BorderLayout.CENTER);		
	}
	
	/*
	 * Used to decript back to String an array of serialVersionUID encoded by this program
	 * Yoy will have to cut & paste this method into your production code
	 */
	private String decrypter(long[] codedUid) {
		int len = codedUid.length;
		if(len == 0)
			return "";
		// StringBuilder where we will decompose the hidden STring
		StringBuilder sb = new StringBuilder(len * NB_CHAR);
		--len;
		// loop in reverse
		for(int i = len; i >= 0; --i) {
			// until all chars extracted
			long tmp = codedUid[i];
			while(tmp > 0) {
				// extract rightmost char
				char c = (char) (tmp % 0xFF);
				// into the StringBuilder
				sb.insert(0, c);
				tmp /= 0xFF;
			}
		}
		return sb.toString();
	}
	
	// the standarnd method to start the whole damned thing
	public static void main(String[] args) {
		JFrame frame = new JFrame("Encryption in serialVersionUID");
		frame.add(new UIDHidder());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(800, 600);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		
	}

	/*
	 * Extends JTable just to be able to set the cell renderer
	 */
	class MyTable extends JTable {

		private static final long serialVersionUID = 1L;
		// to save the model which is also the renderer
		TableCellRenderer model;
		
		// receives as parameter the TableModel which is also a TableCellRenderer
		MyTable(MyModel model) {
			super(model);
			this.model = model;
		}
		/** tell to call the Model which is also a renderer for all rendering (we return JLabel) */
		public TableCellRenderer getCellRenderer(int row, int col) {
			return model;
		}

	}

	/*
	 * To feed the JTable with the appropriate data
	 * Col: 1 the number of the class
	 * Col: 2 the serialVersionUID 
	 */
	class MyModel extends AbstractTableModel implements TableCellRenderer {

		private static final long serialVersionUID = 0x1L;
		
		// the label that will be displayed in the JTable
		private JLabel label = new JLabel();
		// the table header
		private String[] header = {"Class name", "serialVersionUID"};
		
		// always two column
		public int getColumnCount() {
			return 2;
		}

		// returns the number of serialVersionUID
		public int getRowCount() {
			return uid.length;
		}

		// first column is class number second column the serialVersionUID
		public Object getValueAt(int row, int col) {
			if(uid.length == 0)
				return null;
			String str;
			// first column
			if(col == 0)
				str = "   Class_" + (row + 1);
			else
				str = String.format("0x%XL   ", uid[row]);
			return str;
		}

		// return the 2 column headers
		public String getColumnName(int col) {
			return header[col];
		}

		public Component getTableCellRendererComponent(JTable arg0,
				Object arg1, boolean arg2, boolean arg3, int row, int col) {
			if(arg1 == null) {
				label.setText("");
			}
			else {
				if(col == 0)
					label.setHorizontalAlignment(SwingConstants.CENTER);
				else
					label.setHorizontalAlignment(SwingConstants.RIGHT);				
				label.setText((String) arg1);
			}
			return label;
		}
		
	}
	
	/**
	 * A listener to be informed whenever the JTextField for the string to encode changed
	 */
	class EncryptListener implements DocumentListener {

		// when document changes
		public void changedUpdate(DocumentEvent arg0) {
			// clear the textArea in any case
			codeText.setText("");
			// get the String from the JTextField
			String str = txtField.getText().trim();
			// if empty String ignore the request
			int len = str.length();
			if(len == 0) {
				uid = new long[0];			// for the JTable to know nothing to display
				labelBack.setText("Translated back:");
				return;
			}
			// convert the String to encrypt into char
			char[] digit = str.toCharArray();
			// so we will use NB_CHAR digits from the string to build serialVersionUId
			int nbSerial = digit.length / NB_CHAR;
			// if not an exact multiple of NB_CHAR we need one more
			if(len % NB_CHAR != 0)
				++nbSerial;
			
			uid = new long[nbSerial];
			// cumulate the char in longwords
			for(int i = 0; i < len; ++i) {
				int k = i / NB_CHAR;			// index of the uid
				uid[k] *= 0xFF;
				uid[k] += digit[i];
			}
			// inform table changed
			table.tableChanged(null);
			// display decodes Sring
			labelBack.setText("Translated back: \"" + decrypter(uid) + "\"");
			
			// prepare the txtArea
			StringBuilder sb = new StringBuilder();
			sb.append("   // UID to cut & paste in your different classes\n");
			for(int i = 0; i < nbSerial; ++i) {
				sb.append("   public static final long serialVersionUID = 0x");
				sb.append(String.format("%X", uid[i])).append("L;     // in Class_").append((i+1));
				sb.append("\n");
			}
			sb.append("\n\n");
			sb.append("   // code to execute to decipher\n");
			sb.append("   long[] uids = new long[").append(nbSerial).append("];\n");
			for(int i = 0; i < nbSerial; ++i) {
				sb.append("   uids[").append(i).append("] = Class_").append((i+1)).append(".serialVersionUID;\n");
			}
			// and the translation
			sb.append("\n   // get translation using the method provided within that code\n");
			sb.append("   String str = decrypter(uids);\n");
		    codeText.setText(sb.toString());
		}

		@Override
		public void insertUpdate(DocumentEvent arg0) {
			changedUpdate(arg0);
		}
		@Override
		public void removeUpdate(DocumentEvent arg0) {
			changedUpdate(arg0);
		}
	}

}


Was This Post Helpful? 4
  • +
  • -

#14 g00se  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2777
  • View blog
  • Posts: 11,758
  • Joined: 20-September 08

Re: Protect plain string from decompilers

Posted 11 January 2011 - 03:27 AM

Right ;) You don't need to worry about the long being +ve/-ve in fact - it's just a bit pattern so you can safely handle 8 'ascii' characters

btw, how do you read the serialVersionUIDs (they're private) ?

http://download.orac...class.html#4100

This post has been edited by g00se: 11 January 2011 - 05:00 AM

Was This Post Helpful? 0
  • +
  • -

#15 pmiller624  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 55
  • Joined: 02-May 10

Re: Protect plain string from decompilers

Posted 11 January 2011 - 12:55 PM

Forgive me, I'm still trying to understand the concept of serialVersionUIDs.

How will this protect the string if all that needs to be called is the decrypter method?
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2