#3. Encrypted the whole class with javax.crypto

January 22, 2009

Many may have been googled around with this very topic and have came across with many example; but most of them haven’t depicted the practical one.

So, here I tried to conduct practical one. Hope this will help :D

We’ll started with how to generated the SecretKey without creating a new one every time you have run the software (no more random).I’ll illustrate this example with the “DES” algorithm. The “DES” algorithm required at least 8 bytes key. Here is SecretKey generator function.

   1: public static SecretKey generateKey(String pass) 
   2:     throws InvalidKeyException 
   3: {
   4:         SecretKey key = null;
   5:         
   6:         DESKeySpec ks = new DESKeySpec( pass.getBytes() );    // required 8 bytes at least
   7:         SecretKeyFactory factory;
   8:         try {
   9:             factory = SecretKeyFactory.getInstance( "DES" );
  10:             key = factory.generateSecret( ks );
  11:         } catch (NoSuchAlgorithmException e) {
  12:             e.printStackTrace();
  13:         } catch (InvalidKeySpecException e) {
  14:             e.printStackTrace();
  15:         }
  16:         return key;
  17:     }

After you have a function for generated the key; Let’s translate your class to array of byte and vice versa.

   1: public static byte[] createByteArrayFromObject(Serializable o) throws IOException {
   2:     ByteArrayOutputStream baos = new ByteArrayOutputStream();
   3:     ObjectOutputStream oos;
   4:     oos = new ObjectOutputStream(baos);
   5:     oos.writeObject(o);
   6:     oos.close();
   7:     return baos.toByteArray();
   8: }
   9:  
  10: public static Object createObjectFromByteArray(byte[] byteObject) throws IOException, ClassNotFoundException {
  11:     ByteArrayInputStream bais;
  12:     ObjectInputStream ois;
  13:     bais = new ByteArrayInputStream(byteObject);
  14:     ois = new ObjectInputStream(bais);
  15:     return ois.readObject();
  16:     
  17: }

This is how to encrypt the class; supply the class’s array of byte through bytes parameter.

   1: public static String encryptBytes(SecretKey key, byte[] bytes) {
   2:     try {
   3:         Cipher ecipher = Cipher.getInstance("DES");
   4:         ecipher.init(Cipher.ENCRYPT_MODE, key);
   5:  
   6:         // re-adjust the bytes accordingly to the protocol
   7:         byte[] arranged = bytes;
   8:         
   9:         // Encrypt
  10:         byte[] enc = ecipher.doFinal(arranged);
  11:  
  12:         // Encode bytes to base64 to get a string
  13:         return new sun.misc.BASE64Encoder().encode(enc);
  14:     } catch (javax.crypto.BadPaddingException e) {
  15:     } catch (IllegalBlockSizeException e) {
  16:     } catch (javax.crypto.NoSuchPaddingException e) {
  17:     } catch (java.security.NoSuchAlgorithmException e) {
  18:     } catch (java.security.InvalidKeyException e) {
  19:     }
  20:     return null;
  21: }

Now to decrypt:
   1: public byte[] decryptBytes(String str) {
   2:     try {
   3:         Cipher dcipher;
   4:  
   5:         dcipher = Cipher.getInstance("DES");
   6:         dcipher.init(Cipher.DECRYPT_MODE, key);
   7:  
   8:         // Decode base64 to get bytes
   9:         byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
  10:  
  11:         // Decrypt
  12:         byte[] unarranged = dcipher.doFinal(dec);
  13:         // re-adjust the bytes accordingly to the protocol
  14:         byte[] arranged = unarranged;
  15:         
  16:         return arranged;
  17:     } catch (javax.crypto.BadPaddingException e) {
  18:     } catch (IllegalBlockSizeException e) {
  19:     } catch (UnsupportedEncodingException e) {
  20:     } catch (java.io.IOException e) {
  21:     } catch (javax.crypto.NoSuchPaddingException e) {
  22:     } catch (java.security.NoSuchAlgorithmException e) {
  23:     } catch (java.security.InvalidKeyException e) {
  24:     }
  25:     return null;
  26: }

 
Now encrypted this class’s array of byte with the key generated by the first function.
 
encrypt:
 
   1: String password = "this is the password string used as key to encrypt";
   2:  
   3: SecretKey key = generateKey(password);
   4:  
   5: ObjectToEncrypt ote = new ObjectToEncrypt();
   6: String encryptedString = encryptBytes(key, createByteArrayFromObject(ote)); 

 
decrypt:

   1: String password = "the same password that used earlier";
   2:  
   3: String encryptedString = "...."; // this is encrypted string
   4:  
   5: SecretKey key = generateKey(password);
   6:  
   7: ObjectToEncrypt ote = (ObjectToEncrypt) createObjectFromByteArray(decryptBytes(key, encryptedString));

Note that the object to encrypted/decrypted must implements Serializable.

#2. Create a thread with class’s method.

January 14, 2009

In C/C++ starting the thread requires a static function as a starting address. Thus, in case that you want to invoke the thread with the target class’s method is a little bit complicated.

Here is a way that you can make it happen :D

First of, we got a very simple class name CSample and you want to create a thread with your own class method in order to let your thread has an access to your class memory space. In this example let’s say that function is named as targetFunctionToCall()

Now to create thread with this function simply you are required to have a static method to invoke this function first. I’ll name it with s_ prefix which stands for static.

In the implementation part we will create the thread with the static function s_targetFunctionToCall. And in this function it’ll invoke your targetFunctionToCall again. Here is what your header files would look like.

csample.h

   1: class CSample
   2: {
   3: public:
   4:     CSample();
   5:     virtual ~CSample();
   6: 
   7:     static void s_targetFunctionToCall(void *);
   8:     void targetFunctionToCall();
   9: };

 

csample.cpp

   1: #include "csample.h"
   2: 
   3: CSample::CSample()
   4: {
   5:     ::CreateThread(NULL, 0, (unsigned long (__stdcall *) (void *)) s_targetFunctionToCall, (void *) this, 0, NULL);
   6: }
   7: CSample::~CSample()
   8: {
   9: }
  10: void CSample::s_targetFunctionToCall(void * instance)
  11: {
  12:     ((CSample *) instance)->targetFunctionToCall();
  13:     ::ExitThread(0);
  14: }
  15: void CSample::targetFunctionToCall()
  16: {
  17:     // do your things
  18: }

 

As you can see the s_targetFunctionToCall redirect the code flow back to the old class by the instance parameter.

You can also modify your arguments since void * can pass anything to it, you may modify it with expansion with struct that packed everything you need inside and then pass it through.

Hope this will help :)

#1. Red5’s “Hello, World.”

November 7, 2008

Intro.

As the very first entry of my very first blog :D . Let me describe about what I’m gonna talking about. The Red5, is an open-source data service for flex technology. Many that has been working around the flex should have known this software for quite sometime. But for those who don’t; Flex data service, or from my understanding, it’s a server side of the software. It’s can provided many various kind of service. The Red5 act upon the basis of connection providing between client-server and from that point it’s also provided the client-client.

Now, that’s too much for the brief you can certainly find out more information from their Red5 official site. So, finally, here is the main idea of this entry: “How to use this Red5?”.

Here are some basic example of our well known “Hello, World”.

Let’s start with server side first.

  1. download the red5 from their svn link address.
  2. open your eclipse, import the project.
  3. create a new folder in webapps/[your project’s name]/WEB-INF/src. And link that as a source folder.
  4. in your project folder, with sub directory “WEB-INF” make sure it contains these files (these files can be copies from the template directory located in doc/templates/myapp/WEB-INF).
    1. red5-web.properties
    2. red5-web.xml
    3. web.xml
  5. leave these 3 files as it be first. We’ll come back to it later.
  6. Now let’s start coding!.

Server Side: Java.

From my pov; I rather prefer jdk1.6 instead of 1.5.

To create a new application for Red5 server, that allows an access from client side. You can easily extends the ApplicationAdapter class of Red5.

   1: public class Application extends ApplicationAdapter {
   2:  
   3:     private static final Log log = LogFactory.getLog( Application.class );
   4:  
   5:     @Override
   6:     public boolean appStart(IScope scope)
   7:     {
   8:         // initialize application.
   9:         log.info("Application.appStart()");        
  10:         return true;
  11:     }
  12:  
  13:     @Override
  14:     public boolean appConnect( IConnection conn , Object[] params )
  15:     {
  16:         log.info("Application.appConnect()");
  17:         return true;
  18:     }
  19:  
  20:     @Override
  21:     public void appDisconnect( IConnection conn )
  22:     {
  23:         log.info( "Application.appDisconnect()");
  24:         super.appDisconnect( conn );
  25:     }
  26:  
  27:     @Override
  28:     public void appStop( IScope app )
  29:     {
  30:         log.info( "Application.appStop()");
  31:         super.appStop( app );
  32:     }
  33: }

this is a very basic code. Which do exactly nothing, just allow the client connect to the server. Now let’s add some method for the client to call from their side.

   1: public String hello(String words) {
   2:     return "Hello " + words;
   3: }

the code above is a function that allow the calls from the client which contains one argument, and reply back with the “Hello “ concats to it’s head, and this will be called from client.

That’s much for the server’s code for now.

Server Side: Configure xml files.

Now to enable the Red5 to knows your application, we need to configures the xml file that we left earlier.

  • red5-web.properties
      •    1: webapp.contextPath=/[your project folder name] 
           2: webapp.virtualHosts=localhost,127.0.0.1 

  • red5-web.xml
    • in this file it’s defined the class path that reference to the certain class that will be executed on the client’s requests. Locate the bean with id of “web.handler” and supply your class path to your Application class.
    •    1: <!-- Customized software spring injection -->
         2: <bean id="web.handler" 
         3:     class="class.path.to.your.Application"/>

  • web.xml
    • this file state the lookup path for your application. Configure the parameter by name webAppRootKey will be suffice.
    •    1: <context-param>
         2:     <param-name>webAppRootKey</param-name>
         3:     <param-value>/[your project's name]</param-value>
         4: </context-param>

that’s much for the configuration you will touch these files again only when you need to add services in your application.

Client Side: Flex.

For flex, create a new actionscript class, To calls the server side. you only need a NetConnection class to made the call to your server. Here is the code sample.

   1: package com.sylli.mce.flex.client
   2: {
   3:     import flash.events.NetStatusEvent;
   4:     import flash.net.NetConnection;
   5:     import flash.net.ObjectEncoding;
   6:     import flash.net.Responder;
   7:     
   8:     public class Red5Facade
   9:     {
  10:         private var m_nc:NetConnection;
  11:         private var m_rs:Responder;
  12:  
  13:         /* constructor */
  14:         public function Red5Facade( )
  15:         {
  16:             trace("Establish connection. ");
  17:  
  18:             // create responder for string return-type.
  19:             m_rs = new Responder(debugStringResponderFunction, null);            
  20:  
  21:             m_nc = new NetConnection( );    // new netconnection
  22:             m_nc.objectEncoding = ObjectEncoding.AMF0;
  23:  
  24:             // netstatus event listening
  25:             m_nc.addEventListener( NetStatusEvent.NET_STATUS , netStatus );
  26:             
  27:             // connect to red5, passing false as parameter
  28:             m_nc.connect( "rtmp://localhost/[your project's name]" );
  29:         }
  30:  
  31:         private function netStatus ( event:NetStatusEvent ):void
  32:         {
  33:             trace( "NetStatus: " + event.info.code );
  34:             if ( event.info.code == "NetConnection.Connect.Rejected" )
  35:             {
  36:                 // trace reject message
  37:                 trace( event.info.application );
  38:             }
  39:         }
  40:  
  41:         public function helloWorld ( words:String ):void
  42:         {
  43:             m_nc.call("hello", m_rs, words); 
  44:         }
  45:  
  46:         protected function debugStringResponderFunction(_val:String):void
  47:         {
  48:             trace("String returns " + _val);
  49:         }
  50:     }
  51: }

Finally, the test drive, with your eclipse start the Red5 server by create new run, using org.red5.server.Standalone which will starts all the server nodes existing in their webapps directory.

Then start debug your flex application, try call your class methods. if it made a proper connection to the red5’s. (start as a debug mode, so the trace() function would print properly.

 

Hope this will help. Any comments will be appreciated.


Follow

Get every new post delivered to your Inbox.