Encrypt/Decrypt message using PGP

Here I am sharing my code when, using PGP, I had to encrypt/sign a JSON request to be the request body, and also to decrypt/verify a response body to see the JSON response.

It’s in Groovy Java. Thank you to Bouncy-GPG for providing the framework on top of Bouncy Castle. It worked well in my project.

How they work is explained in the code comments.

Hopefully this helps.

import java.nio.charset.Charset
import java.security.NoSuchAlgorithmException
import java.security.NoSuchProviderException;
import java.security.Security
import java.security.SignatureException
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.BouncyGPG
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.callbacks.KeyringConfigCallbacks
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.keyrings.KeyringConfig
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.keyrings.KeyringConfigs
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.bouncycastle.util.io.Streams


class PayloadService {
    /**
     * On sending
     *
     * To encrypt request payload, to be the request body
     *
     * The PGP works as follow:
     * First, creates a key to encrypt the payload, 
     * then encrypts the key using the recipient's public key.
     * Then encrypts the payload using that key.
     * Then signs the encrypted payload using the sender's signature,
     * so the recipient is sure that this is really from the sender.
     *
     * @param sourceText, i.e. the payload string 
     * @param pubKeyRing, sender's public key ring, containing also the recipient's public key
     * @param privKeyRing, sender's private key ring
     * @param privKeyPwd, sender's private key password
     * @param sender, corresponds with user id in sender's key
     * @param recipient, corresponds with user id in recipient's key
     *
     * @return the encrypted message i.e. PGP message, must be set with UTF-8
     */
    String encryptAndSign(String sourceText, File pubKeyRing, File privKeyRing, String privKeyPwd, String sender, String recipient)
            throws IOException, PGPException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException
    {
        installBCProvider()

        KeyringConfig keyringConfig = KeyringConfigs.withKeyRingsFromFiles(pubKeyRing,
                privKeyRing, KeyringConfigCallbacks.withPassword(privKeyPwd))

        ByteArrayOutputStream cipherStream = new ByteArrayOutputStream()

        OutputStream encryptionStream = BouncyGPG
                .encryptToStream()
                .withConfig(keyringConfig)
                .withStrongAlgorithms()
                .toRecipient(recipient)
                .andSignWith(sender)
                .armorAsciiOutput()
                .andWriteTo(cipherStream)
        encryptionStream.write(sourceText.getBytes())
        encryptionStream.close()

        cipherStream.close()

        byte[] cipherBytes = cipherStream.toByteArray()

        return new String(cipherBytes, Charset.forName("UTF-8"))
    }

    /**
     * On receiving
     *
     * To decrypt response body, to see the response payload
     *
     * The PGP works as follows:
     * Decrypts the key (to open the payload) using recipient's private key.
     * It's possible because the key was encrypted using the recipient's public key.
     * Then, using that key, decrypts the payload.
     * Then, using the sender's signature, verifies if the payload is really
     * from the sender.
     *
     * @param cipherText, the PGP message to be decrypted 
     * @param pubKeyRing, recipient's public key ring, containing also the sender's public key
     * @param privKeyRing, recipient's private key ring
     * @param privKeyPwd, recipient's private key password
     * @param sender, corresponds with user id in sender's key
     *
     * @return the original text, must be set with UTF-8
     */
    String decryptAndVerify(String cipherText, File pubKeyRing, File privKeyRing, String privKeyPwd, String sender)
            throws IOException, PGPException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException
    {
        installBCProvider()

        KeyringConfig keyringConfig = KeyringConfigs.withKeyRingsFromFiles(pubKeyRing,
                privKeyRing, KeyringConfigCallbacks.withPassword(privKeyPwd))

        ByteArrayInputStream cipherStream = new ByteArrayInputStream(cipherText.getBytes());

        InputStream decryptedStream = BouncyGPG
                .decryptAndVerifyStream()
                .withConfig(keyringConfig)
                .andRequireSignatureFromAllKeys(sender)
                .fromEncryptedInputStream(cipherStream)

        byte[] decryptedBytes = Streams.readAll(decryptedStream)

        return new String(decryptedBytes, Charset.forName("UTF-8"))
    }

    /**
     * Call this before all PGP works,
     * as we are using Jens Neuhalfen's library based on Bouncy Castle
     */
    private void installBCProvider() {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider())
        }
    }
}

Lazy Loading in Ionic 3

What is Lazy Loading?
  • Angular is a one page app.
  • Without lazy loading, all pages are loaded at the start of the app. With lazy loading, a page is loaded only when it is needed.
  • Therefore, for app with many pages, lazy loading allows faster initial load of the app, which should give better user experience.
How to do it in Ionic 3?

Briefly

  1. Add “@IonicPage()” decorator in every lazy-loaded page
  2. Create a module file, which imports “IonicPageModule”
  3. This page is not imported from anywhere. It is referred by calling its name as string
    e.g. navCtrl.push(‘ComponentName’) instead of navCtrl.push(ComponentName)

In more details

When a page has @IonicPage() decorator, the compiler knows that the page is a lazy-loaded page. For example, I have BookingPage defined in booking.ts


import { IonicPage } from 'ionic-angular';
...
@IonicPage()
@Component({
  selector: 'page-booking',
  templateUrl: 'booking.html'
})
export class BookingPage {
  ...
}

The compiler knows that the above is a lazy loaded page. The compilation will automatically look for booking.module.ts, which imports
IonicPageModule.forChild(BookingPage). So we need to create the module like that below.


import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { BookingPage } from './booking';
...

@NgModule({
  declarations: [
    BookingPage,
    ...
  ],
  imports: [
    IonicPageModule.forChild(BookingPage),
    ...
  ],
  exports: [
    BookingPage,
    ...
  ]
})
export class BookingPageModule { }

Both the above booking.ts and booking.module.ts are not imported from anywhere. They are linked in the project internally by Ionic 3. We just need to have those two files.

As BookingPage is not imported from anywhere, how do we show it? It’s by calling its name as string. For example when it is to be shown using a navigation controller, we call:

navCtrl.push('BookingPage')

instead of

navCtrl.push(BookingPage)

As usual, nothing new here, many people have done this. Just my note. Have a great day!

Set to nil – Release

I was checking the consequences of setting a pointer to “nil” and calling “release” on object, in Objective-C when developing an iPhone application.

Here is my understanding.

CASE 1

Person * p = [[Person alloc] init];

NSLog(@"%d", [p retainCount]); // 1

Here, a Person object instance is created in a memory address.
Pointer p points to the memory address of the Person instance.
As set by the memory management in Obj-C. calling [p retainCount] gives 1.

CASE 2

Person * p = [[Person alloc] init];
[p release];

NSLog(@"%d", [p retainCount]); // Error

When [p release] is called, the retain count of the Person instance decreases by one and becomes 0 (As set by Obj-C’s memory management). As the retain count reaches 0 the Person instance is destroyed and its memory address can be claimed by other.

How about the pointer p?

Pointer p still points to the memory address of the destroyed Person instance.
Thus, calling [p retainCount] gives error because p points to memory address of a destroyed object.

CASE 3

Person * p = [[Person alloc] init];
p = nil;

NSLog(@"%d", [p retainCount]); // 0

First, a Person instance is created in a memory address.
Second, by setting pointer p to nil, the following happens: the Person instance is destroyed from its memory address and then pointer p points to nothing.
Why is the Person instance destroyed? It is the way Obj-C is, that is when a pointer pointing to a memory address of an object is set to nil, the object is destroyed, unless case 5 below occurs.

Calling [p retainCount] returns 0. The 0 here is not because the retain count decreases by one, but because a call by a nil pointer is just ignored although no error occurs. We can see the evidence in case 4.

The memory management, however, will detect a leak, because setting p to nil does not decrease the Person instance’s retain counter, and hence the retain counter remains 1, although the Person instance is destroyed (But I can’t seem to get the evidence for this in Leaks instrument, as it does not show the leak).

CONCLUDING CASE 2 AND 3

Person * p = [[Person alloc] init];
[p release];
p = nil;

This concludes case 2 and 3.

Some people suggests to set pointer p to nil after [p release]. The purpose is to prevent error when there is an unexpected method call on p later on.

In dealloc method, however, setting p=nil is not necessary, because in dealloc method such pointer p will be cleaned.

CASE 4

Person * p = [[Person alloc] init];
[p retain];

NSLog(@"%d", [p retainCount]); // 2

p = nil;

NSLog(@"%d", [p retainCount]); // 0

First, a Person instance is created in a memory address.
Second, by calling [p retain], the retain count of the Person instance increases by one, so [p retainCount] gives 2.

Third, by setting p to nil, the Person instance is destroyed from its memory address, and then pointer p points to nothing. Calling [p retainCount] now gives 0 because the call is just ignored (as that in case 3).

The memory management still records that the retain count is 2, however, and so a memory leak will be reported, although the Person instance is destroyed.

CASE 5

Person * p1 = [[Person alloc] init];
Person * p2 = p1;
p1 = nil;

NSLog(@"%d", [p2 retainCount]); // 1

Pointer p2 points to the memory address of the Person instance, which is the same memory address that pointer p1 points to.

When p1 points to nil, here the Person instance is not destroyed. Why? Because the memory address of the Person instance is still pointed by pointer p2. Therefore calling [p2 retainCount] gives 1.

If the intention is to destroy the Person instance, we need to call “release”, as in case 6 below.

CASE 6

Person * p1 = [[Person alloc] init];
Person * p2 = p1;
[p1 release];

NSLog(@"%d", [p2 retainCount]); // Error

As in the previous scenario, pointer p2 points to the same memory address of the Person instance as that pointed by pointer p1.

Calling [p1 release] causes the Person instance to be destroyed, because the retain count of the Person instance reaches 0 after being decreased by one.

But pointer p2, unfortunately, points to memory address of the destroyed object. Therefore, unlike in case 5, calling [p2 retainCount] gives error.

CASE 7

Person * p1 = [[Person alloc] init];
Person * p2 = p1;
[p2 retain];
[p1 release];

NSLog(@"%d", [p1 retainCount]); // 1
NSLog(@"%d", [p2 retainCount]); // 1

Now, modified from case 6, [p2 retain] is called before [p1 release]. When [p2 retain] is called, the retain counter of the Person instance increases by one, and becomes 2.

Then when [p1 release] is called, the retain counter of the Person instance decreases by one, and becomes 1. Because it does not reach 0, the Person instance is not destroyed, so that at this point both [p1 retainCounter] and [p2 retainCounter] give 1.

CASE 8

Person * p1 = [[Person alloc] init];
People * people = [[NSMutableArray alloc] init];
[people addObject:p1];

NSLog(@"%d", [p1 retainCount]); // 2

[p1 release];

NSLog(@"%d", [p1 retainCount]); // 1

Person * p = (Person *) [people objectAtIndex:0];

NSLog(@"%d", [p retainCount]); // 1

This case seems familiar: a Person instance is created, passed into an array, and then it is released.

When an array adds an object, the object automatically calls “retain”, increasing the retain count of the object by one.

Calling “retain” before [p1 release] is similar to that in case 7, the retain count of the Person instance becomes 2.

When [p1 release] is called, the retain count decreases by one, and becomes 1.

As the evidence for the above, get the object from the array and let it be pointed by a pointer p, then call [p retainCount]. Consistently, it gives 1.

Slightly out of topic here, we may ask when the retain count will reach 0, because otherwise a memory leak occurs. The objectAtIndex automatically calls “autorelease” on the object, so that the object will be destroyed eventually by an autorelease pool.

CASE 9

Person * p1 = [[Person alloc] init];
People * people = [[NSMutableArray alloc] init];
[people addObject:p1];
p1 = nil;

Person * p = (Person *) [people objectAtIndex:0];

NSLog(@"%d", [p retainCount]); // 2

Now, what if p1 is set to nil, instead of released (i.e. calling [p1 release] as in case 8)?

The Person instance is now being used by the People array. Its memory address is being pointed by a pointer somewhere (implemented by array). Therefore, similar to case 4, when setting p1=nil the Person instance is not destroyed. In addition, the retain count of the Person instance does not decrease by one, but remains 2. Thus, [p retainCount] gives 2.

When eventually the object is released (because objectAtIndex automatically calls autorelease), its retain count will become 1. Thus, here a memory leak will occur, because of not only the retain count being more than 0 but also the Person instance being not destroyed.

CASE 10

Person * p1 = [[Person alloc] init];
People * people = [[NSMutableArray alloc] init];
[people addObject:p1];

NSLog(@"%d", [p1 retainCount]); // 2

[p1 release];

NSLog(@"%d", [p1 retainCount]); // 1

[people replaceObjectAtIndex:0 withObject:[NSNull null]];

NSLog(@"%d", [p1 retainCount]); // Error

This case is slightly out of topic here. It just checks replaceObjectAtIndex method on the array.

With replaceObjectAtIndex, the object is firstly removed from the location in the array before being replaced. When removing an object from an array, “release” is automatically called on the object. Therefore, the “release” decreases the Person instance’s retain count by one, making it reach 0, leading to the Person instance being destroyed.

Therefore the last [p1 retainCount] call gives error, because pointer p1 points to the memory address of the destroyed Person instance.

Conclusion
Only when the object, to which a pointer points, has been destroyed in its memory address, can the pointer be set to nil safely. Otherwise, there are consequences, as described in case 3, 4, 5 and 9.

gPHPEdit – the PHP editor I choose

My search for a suitable PHP editor ended up with gPHPEdit.

The search began when jEdit, once an excellent editor I always used, often halted my work. When typing using jEdit, my keyboard was often locked up, so I couldn’t type anything in jEdit although all other system worked normally. This Sun forum let me know that this issue seemed to be something that many people had been waiting to be fixed. (It seemed to be a bug in Java Swing in Linux. Yes, I was using Linux – Fedora 6).

Browsing a bit, I found a list of PHP editors available, some of which had already been familiar to me.

First I tried Eclipse because I wanted to try the most recent version i.e. 3.3.1 (The last time I used Eclipse was about a year ago). I used PDT plugin to PHP-enable the Eclipse. The look and feel and the functionalities looked good. However, when I wanted to edit a PHP file whose extension was .module (I developed a Drupal file), the Eclipse didn’t syntax-highlighted the code although I had followed all instructions to PHP-syntax-highlight non .php files in Eclipse. Moreover, I felt quite heavy launching the Eclipse, which also consumed much of memory and CPU of my 512MB-RAM 1GHz-PIII laptop. I thought it was too big for only a PHP editor.

Then I tried KDevelop, which was actually already in my Fedora 6. It launched much quicker than Eclipse. However, I found the PHP codes were not easy to read, because some guides in the editor looked too distracting to me, and I could not remove the guides to make the codes clearer to read.

Next, I tried Bluefish, which had been in my Fedora 6. The launch was fast, it didn’t consume much memory and CPU of the laptop, and it seemed to be well established. But there were some things that I was not happy with. First, the directories shown nested at the left sidebar was too wide, so that to finally show the directory I was working with, the sidebar had to be widened much. Second, the functions in the list at the sidebar were not those in my PHP code, but function references as those in php.net. I needed to have a list of functions in my code, in which clicking a function in that list could bring me straight to that in the code. Well, I thought, if I got no other alternative I would go with Bluefish anyway.

Feeling a bit exhausted but was still curious, I walked through the list again.

Then I tried gPHPEdit. I picked it because the name gave me a sense that it was a Gnome version of phpEdit, a well known but non-free one. Although gPHPEdit’s last update, i.e. version 0.9.91, was in 2006, I downloaded it anyway. I installed it by compiling the source into my /usr/local directory. The compilation was quick, it seemed lightweight.

I entered “module” into “Recognized PHP file extensions” form. I set “fxd” sized 10 as the font of the editor.

Then guess what? Yes, gPHPEdit gave me what I needed. It provided a clear view of my codes, recognized different PHP file extensions, was quick to launch, didn’t consume much memory and CPU of the old laptop and provided a browser for all functions in my code (which could be turned on/off) in which clicking a function there would direct me straight to that in the code. Moreover, the user interface was just clear and simple to me. All those were just what I needed. In addition, actually it was able to syntax-highlight PHP, CSS, HTML, XML, Python, C/C++, Perl and SQL.

I stopped walking through the list, because all in all gPHPEdit satisfied my needs. It made my PHP coding more enjoyable and so I tended to be more productive compromising my time for searching a suitable PHP editor ๐Ÿ™‚ at least for now. To the developers: “Big thanks”.

Installing Drupal using XAMPP in iMac

I was trying to install Drupal in the iMac, using XAMPP. So I downloaded XAMPP for Mac OS X and installed it. Then I put my Drupal into the /Applications/xampp/xamppfiles/htdocs directory.But what I got in the browser (http://localhost/drupal) were some errors like internal server error, forbidden access and exhausted memory.To fix them, I did as follows:

  • Altered ย the “etc/httpd.conf” ย so that under the document root directory, the “AllowOverride” is set to “All”:
    Options Indexes FollowSymlinks ExecCGI Includes
    AllowOverride All
    Order allow, deny
    Allow from all
  • Make .htaccess readable, by chmod a+r .htaccess
  • In “etc/php.ini”, set memory_limit variable value to 64M (the default was 8M)

Restart the Apache and done, until further problem ๐Ÿ™‚

First review on iMac desktop 20″

This is my first use of iMac aluminum 20″ screen. I “played” with it a bit. This is my opinion.

The look:

  • Pretty
  • Just nice

The hardware

  • Mouse:
    • Need to set the accelerator to maximum, otherwise the journey for my hand is too long for that 20″ screen.
    • Emulated to 2 buttons, need to press Control key and click the mouse together to represent the right button. I like 2-button mouse better.
  • Keyboard: soft enough to type and cute enough to look
  • Monitor: sharp enough and beautiful enough to accommodate my background photo

The software

  • OpenOffice (as I believe in it, and as MS Office is very expensive)
    • To install OpenOffice, first we need to install X11. Insert the provided Mac OS X Install Disc 1, scroll down, choose Optional softwares and tick X11. After installing X11 we can install OpenOffice. I installed the 2.2 one.
    • For printing OpenOffice documents, as my printer is Canon Mp150, first I downloaded the driver from Canon website. However, the printing result of my OpenOffice document was not ok. Then I downloaded and installed gutenprint-5.1.3 so that I had 2 printers on the printer list: MP150 and MP150-gutenprint, but still, the result was not as expected: the black looks rather grey. So my solution was to export my OpenOffice document into PDF, then printed the PDF one using the MP150 one.
    • Another alternative for printing OpenOffice is to use PrintFab, but PrintFab driver is not free and is expensive. I just installed the demo version of it and the printing result seems to be ok, but I will do some more testing later.
    • I also downloaded NeoOffice and used the native driver for mac. The printing result was OK, although a color page using PrintFab looked a bit better.
  • Transfering files using FTP to iMac
    • Need to firstly set System Preferences -> Sharing, and, first I tried “Windows Sharing”, then mapped a drive from my Windows-based laptop to the iMac. The file transferring turned out to be very very slow. I had tried to disable ipv6 as some people had suggested but still got almost similar result: very very slow. Steve and Bill seem to be in cold relationship ๐Ÿ™‚
    • Then I tried “FTP Access” instead of “Windows Sharing”. Then using gFtp I transferred files from my Linux to the iMac, and the speed was fast as expected. Steve and Linus look to be in warm relationship ๐Ÿ™‚
  • Sharing files between users of the iMac
    • Need to put the shared files into /users/shared directory
    • Is there other way, like setting my directory as shared like that in Windows?
  • Setting root password: here contains the info.
  • SecondLife is OK
    • The picture and the sound of my SecondLife were OK
  • For chatting, I downloaded Adium instead of iChat, because I have yahoo, msn, google talk, and it works as expected.
  • Being curious if Ubuntu can be read, I inserted the 7.04 Live CD and hoped that the live CD worked well. But after a while a blank page with command prompt appeared. But Ubuntu in Vmware Fusion is OK.
  • I think Apple interface is a bit confusing for a first-timer. My wife clicked on Adobe Reader icon at the bottom but could not get it shown. She said that she had clicked it several times but the Adobe Reader still didn’t show up. After a while I checked that actually it showed up and its menu was at the top, the Adobe name appeared next to the blue Apple icon in the menu line. The menu of Mac softwares looks the same: at the top, in all applications. I think a first timer will find it too far to notice, especially in a big screen. We get used to have a software popped out in a new window when it’s first opened.
  • iPhoto: just nice
  • iMovie: just wonderful
  • iDVD: coool

To conclude, for now I like the iMac. There are issues that we need to get familiar with but I find them minor compared to the wonderful look, features and functionalities.

I won the world tennis tournament!

..can you believe it? Surely naaaa. It’s a just in a game in my k610i sony mobile phone (which was free by subscribing to Singtel).

However, although it is only a game, it was really challenging to me. I mean it. I am a real tennis player too.

The game consists of 6 tournaments, each of which has 5 matches.

To finally become the champion, I went through really tough matches. The toughest matches were those towards the end i.e. with some eastern Europeans, then with Hennin and finally with Lindsay Davenport. Yeaaah.. they are women tournaments.. you may mourn, but what’s the difference between woman and man in a computer game? Just the dresses, right?

I experienced that, we couldn’t win if we were just a base liner relying on power and angle of our swings. I had to play volley behind the net, sometimes half volley. Also I had to learn the opponent’s body language, if I am not exaggerating, to identify where a return ball would fall.

Moreover, I must never never underestimate the opponent. I might believe that I returned a ball magnificently with my magnificent swing, only to find that the opponent returned it more magnificently.

Now, what can be learned? To me, nothing seems to be more valuable than the spirit that pulls me into doing practice practice practice for the game. This was like a real situation in tennis.

Fedora core 6 in my T23

I almost replaced my FC6 in my T23 because the fedora often hanged up. I have tried removing services, changing kernel versions, uninstalling suspicious packages, but none of them were successful.

Yesterday night I visited this forum and after identifying some of the clues there, now my FC6 seems to be running smoothly. It has been running for more than 8 hours now. Then I shared this in that forum.

The most recent Fedora is FC7 now, but it didn’t install well in my T23. So I am using FC6. I feel like FC6 will be the last Fedora in my T23. When later on someday FC6 is out-of-date, probably I will go with Ubuntu.

I let my eyes be wet writing this post, because I have been loyal to Fedora/Redhat since Redhat 5.1 in 1999!

SOA in Ministry of Education

educationHere I wrote my thoughts regarding SOA (Service Oriented Architecture) in Ministry of Education, which may be good to be shared.

Basically, I tried to identify issues in a ministry of education. Then I wondered whether computing system adopting SOA could contribute to addressing the issues. I consulted the issues from, first, notes made by Brotosiswojo who was an officer in the ministry of education in Indonesia for about 20 years. Also, I consulted some notes by Drost, whom, although I’ve never met, I admired. From his notes, and from hearing from other people’s stories, I think Drost is a person who has strong determination to improve the quality of life of people. Although the issues were in Indonesia, I believe to some extent they are also found in other countries.

Click here for the article, in PDF