Introduction
In this tip, we shall see how Java can run the code remotely.
Background
In my previous tip, I introduced the way to validate clients Using JNI in java.
In this tip, we will send the request of a hash string from "Using JNI" topic and get back Java source code, then compile and run it.
Using the Code
The attached code is built using C# 2005 and Java 6.0. It has:
- Java Application
- C# class
- ASP.NET Page
Let's break it down
First, we create an XML file which has Java code named HelloWorld.xml...
="1.0"="utf-8"
<root>
<data>
<classname>HelloWorld</classname>
<code>
<![CDATA[
</code>
</data>
</root>
...using C# to encrypt the Java source code into HelloWorld.src and store it on your web server. Later, the client will download HelloWorld.src after an authentication has been success validated.
rgbKey
has 8 bytes as 0xB6,0xCA,0x61,0xAF,0x59,0x1F,0xF3,0xD9
rgbIV
has 8 bytes as 0x74,0x9D,0xEF,0xE7,0x38,0x05,0x30,0x71
rgbKey
and rgbIV
will be used to decrypt HelloWorld.src on the client side.
using System;
using System.Xml;
using System.IO;
using System.Reflection;
public class Test
{
public void run(){
this.path=Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
XmlDocument obj=new XmlDocument();
obj.Load(path+@"\HelloWorld.xml");
EnCrypt.WriteToSteps(path+@"\HelloWorld.src",EnCrypt.EncryptString(obj.OuterXml));
}
}
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
public class EnCrypt
{
private static SymmetricAlgorithm mCSP=null;
static EnCrypt()
{
mCSP=new DESCryptoServiceProvider();
mCSP.Mode = CipherMode.CFB;
mCSP.Padding = PaddingMode.Zeros;
}
public static void WriteToSteps(string path, string data)
{
try
{
using (StreamWriter sw = new StreamWriter(path))
{
sw.WriteLine(data);
}
}
catch (Exception ee)
{
}
}
public static string EncryptString(string Value)
{
ICryptoTransform ct = mCSP.CreateEncryptor(new byte[]
{0xB6,0xCA,0x61,0xAF,0x59,0x1F,0xF3,0xD9},new byte[]
{0x74,0x9D,0xEF,0xE7,0x38,0x05,0x30,0x71});
byte[] byt = Encoding.UTF8.GetBytes(Value);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
cs.Write(byt, 0, byt.Length);
cs.FlushFinalBlock();
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
}
Create a web page to authenticate a request from client and send back rgbKey
, rgbIV
and "HelloWorld.src" as string
response.
privatekey: I will present in the next post, in order to decrypt a hash string which is encrypted with publickey.
JAVACLIENT is prefix "JAVA" and host name of client PC as CLIENT, I assume.
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Security.Cryptography" %>
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %>
<script runat="server" language="c#">
void Page_Load(Object sender, EventArgs e)
{
string ret = Request.QueryString.ToString();
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privatekey);
byte[] bytes = ToByteArray(ret);
ret = Encoding.UTF8.GetString(rsa.Decrypt(bytes, false));
if (ret == "JAVACLIENT")
{
Response.Write(ToStringByte(new byte[]
{ 0xB6,0xCA,0x61,0xAF,0x59,0x1F,0xF3,0xD9 }) +
ToStringByte(new byte[] { 0x74,0x9D,0xEF,0xE7,0x38,0x05,0x30,0x71 }) +
"HelloWorld.src");
}
else
Response.Write("");
}
byte[] ToByteArray(String HexString)
{
int NumberChars = HexString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(HexString.Substring(i, 2), 16);
}
return bytes;
}
</script>
In the last part, we create a Java project using JNI to get a hash string of combination "JAVA" prefix and host name of client PC.
String request = new LoadCert().encryptedData("JAVA");
Send request to your web server and get the Java source code.
private String getSource(String request)throws IOException{
String result = new String();
URL endpoint = new URL((new StringBuilder
("http://yourdomainname/veryfy.aspx?")).append(request).toString());
URLConnection con = endpoint.openConnection ();
InputStream in = con.getInputStream();
result = parseISToString(in);
in.close();
return result;
}
Compile the Java source code and call the main
method to run the application.
Points of Interest
What we want to know in this tip is to force Java clients to always download and compile new code during every run, so that we can develop and maintain the Java code independently.
History
- 29th March, 2013: Initial version