Java tutorial
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.bouncycastle.crypto.StreamCipher; import org.bouncycastle.crypto.engines.RC4Engine; import org.bouncycastle.crypto.params.KeyParameter; public class StealthServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String user = request.getParameter("user"); HttpSession session = request.getSession(); StreamCipher inCipher = (StreamCipher) session.getAttribute("inCipher"); StreamCipher outCipher = (StreamCipher) session.getAttribute("outCipher"); if (inCipher == null && outCipher == null) { byte[] inKey = getInKey(user); byte[] outKey = getOutKey(user); inCipher = new RC4Engine(); outCipher = new RC4Engine(); inCipher.init(true, new KeyParameter(inKey)); outCipher.init(false, new KeyParameter(outKey)); session.setAttribute("inCipher", inCipher); session.setAttribute("outCipher", outCipher); } String clientHex = request.getParameter("message"); byte[] clientCiphertext = HexCodec.hexToBytes(clientHex); byte[] clientDecrypted = new byte[clientCiphertext.length]; inCipher.processBytes(clientCiphertext, 0, clientCiphertext.length, clientDecrypted, 0); System.out.println("message = " + new String(clientDecrypted)); String message = "Hello, this is StealthServlet."; byte[] plaintext = message.getBytes(); byte[] ciphertext = new byte[plaintext.length]; outCipher.processBytes(plaintext, 0, plaintext.length, ciphertext, 0); char[] hexCiphertext = HexCodec.bytesToHex(ciphertext); response.setContentType("text/plain"); response.setContentLength(hexCiphertext.length); PrintWriter out = response.getWriter(); out.println(hexCiphertext); } private byte[] getInKey(String user) { return "Outgoing MIDlet key".getBytes(); } private byte[] getOutKey(String user) { return "Incoming MIDlet key".getBytes(); } } class HexCodec { private static final char[] kDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static char[] bytesToHex(byte[] raw) { int length = raw.length; char[] hex = new char[length * 2]; for (int i = 0; i < length; i++) { int value = (raw[i] + 256) % 256; int highIndex = value >> 4; int lowIndex = value & 0x0f; hex[i * 2 + 0] = kDigits[highIndex]; hex[i * 2 + 1] = kDigits[lowIndex]; } return hex; } public static byte[] hexToBytes(char[] hex) { int length = hex.length / 2; byte[] raw = new byte[length]; for (int i = 0; i < length; i++) { int high = Character.digit(hex[i * 2], 16); int low = Character.digit(hex[i * 2 + 1], 16); int value = (high << 4) | low; if (value > 127) value -= 256; raw[i] = (byte) value; } return raw; } public static byte[] hexToBytes(String hex) { return hexToBytes(hex.toCharArray()); } }