Tuesday, September 4, 2007

Implementing Sun RSA CRT Security to secure data

Often times you need to encrypt/cipher data to keep in your datastores in a non human readable format. There are various ways to achieve this and one of the ways is to implement asymmetric encryption or commonly known as key/pair implementation. Key Pair term is used because this implementation involves a pair of distributable Public Keys and a secret Private key. Data Encrypted by your Public Key can only be decrypted by your Private Key. Longer Keys provide stronger encryption but it requires more computation and hence not appropriate for large amounts of data. You may use it to secure small but important data like credentials, social-security numbers etc. The algorithm used in this secure implementation is Chinese Remainder Theorem (CRT) and it is patented by RSA.

Here, I present you a way to implement this into your apps:

=================================================
KeyGen.java
=================================================

import java.security.KeyPair;
import java.security.KeyPairGenerator;

public class KeyGen {

public static void main(String[] args) throws Exception {
String algorithm = "RSA";
KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm);
generator.initialize(1024);
KeyPair keyPair = generator.generateKeyPair();
System.out.println(keyPair.getClass().getName());
System.out.println(keyPair.getPublic().getClass().getName());
System.out.println(keyPair.getPublic());
System.out.println(keyPair.getPrivate());
}

}
=========================
Results:
=========================
java.security.KeyPair

sun.security.rsa.RSAPublicKeyImpl


Sun RSA public key, 1024 bits
modulus: 98677203744446260465542414765650691002275163600893336774030639809055241671590316795866062624226355106366106365150146141568384880010496063021240945844297495973945754466316385920919706173968448314515263558835923413988948374505246140063606334219872299586481788510932872327106443573840159515004641256381252312213
public exponent: 65537


Sun RSA private CRT key, 1024 bits
modulus: 98677203744446260465542414765650691002275163600893336774030639809055241671590316795866062624226355106366106365150146141568384880010496063021240945844297495973945754466316385920919706173968448314515263558835923413988948374505246140063606334219872299586481788510932872327106443573840159515004641256381252312213
public exponent: 65537
private exponent: 66010151355116476266381509769151653939465423309378897073565730501377708014162855770748799174644973590768519601973656972282825907877079480277007252494924174792809949607545280699010499959716736392703906869830507078213365818919271289454064367852372369106548543273821152999734305850287488981430290809005791015693
prime p: 11233688489962973338844802243855066309619057073058245210667885044580710403537025877181943919444268451387897571270403920077238069995990276143846449096478403
prime q: 8784043089018529857113045198094546951702263784704005736527840877045442563172893548671083896835744209733189342603630638586802678054189266328008006731555271
prime exponent p: 8735389670346415723853835420469992359595440538279052938432591629795720945192088633183487587511158716749775486016789364404476959933101247430347784287573925
prime exponent q: 7568240491089313012675972506455997195093153895770273096400217632226802566063759511714930853086457002102541608853878078618832110395774159825400920214596333
crt coefficient: 7682099122771530487734293443893764412335043357041532111008506208973843014546928432001347862281087160360054782853678831202444919205277659896883572013566175

=================================================
PasswordEncrypt.java
=================================================

import java.math.BigInteger;
import java.security.PublicKey;

import javax.crypto.Cipher;

import org.apache.axis.encoding.Base64;

import sun.security.rsa.RSAPublicKeyImpl;

public class PasswordEncrypt {

private static BigInteger mod;
private static BigInteger pubExp;
private static PublicKey key;
private static Cipher cipher;

static
{
try
{
mod = new BigInteger("98677203744446260465542414765650691002275163600893336774030639809055241671590316795866062624226355106366106365150146141568384880010496063021240945844297495973945754466316385920919706173968448314515263558835923413988948374505246140063606334219872299586481788510932872327106443573840159515004641256381252312213", 10);
pubExp = new BigInteger("65537", 10);

key = new RSAPublicKeyImpl(mod, pubExp);
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}

public PasswordEncrypt()
{
super();
}

public static String encrypt(String password) throws Exception
{
// encrypt the password
byte[] data = password.getBytes();
data = cipher.doFinal(data);
return new String(Base64.encode(data));
}

public static void main(String[] args)
{
try{
System.out.println(encrypt("test"));
}catch(Exception ex){System.out.println(ex.getStackTrace());}
}
}

========================
Results:
========================

iMeOizw/O75tdjDSzXSlkUCGahuNYSvhc5oW/jKzV7+hS6eaxtWzbhcssgAd4ygxGbBL3gZxzxEVePRfLedFPqX/DAHMKSVbeCqbtE+1TtHjvIo46SReAahNANvDJnAXmCO2Bp4p+l4hGrTCAz9EXkhUQdel6AIc0DwJOSB0I+4=

=================================================
PasswordDecrypt.java
=================================================
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.RSAPrivateCrtKeySpec;

import javax.crypto.Cipher;

import org.apache.axis.encoding.Base64;

public class PasswordDecrypt {

private static BigInteger mod;
private static BigInteger pubExp;
private static PrivateKey key;
private static RSAPrivateCrtKeySpec keySpec;
private static Cipher cipher;

static
{
try
{
// get out the parts of the private key
BigInteger privExp = new BigInteger("66010151355116476266381509769151653939465423309378897073565730501377708014162855770748799174644973590768519601973656972282825907877079480277007252494924174792809949607545280699010499959716736392703906869830507078213365818919271289454064367852372369106548543273821152999734305850287488981430290809005791015693");
BigInteger p = new BigInteger("11233688489962973338844802243855066309619057073058245210667885044580710403537025877181943919444268451387897571270403920077238069995990276143846449096478403");
BigInteger q = new BigInteger("8784043089018529857113045198094546951702263784704005736527840877045442563172893548671083896835744209733189342603630638586802678054189266328008006731555271");
BigInteger pExp = new BigInteger("8735389670346415723853835420469992359595440538279052938432591629795720945192088633183487587511158716749775486016789364404476959933101247430347784287573925");
BigInteger qExp = new BigInteger("7568240491089313012675972506455997195093153895770273096400217632226802566063759511714930853086457002102541608853878078618832110395774159825400920214596333");
BigInteger crtCoef = new BigInteger("7682099122771530487734293443893764412335043357041532111008506208973843014546928432001347862281087160360054782853678831202444919205277659896883572013566175");

// get the parts of the public key
mod = new BigInteger("98677203744446260465542414765650691002275163600893336774030639809055241671590316795866062624226355106366106365150146141568384880010496063021240945844297495973945754466316385920919706173968448314515263558835923413988948374505246140063606334219872299586481788510932872327106443573840159515004641256381252312213", 10);
pubExp = new BigInteger("65537", 10);

keySpec = new RSAPrivateCrtKeySpec(mod, pubExp, privExp, p,q, pExp, qExp, crtCoef);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
key = keyFactory.generatePrivate(keySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}

public PasswordDecrypt()
{
}

public static String decrypt(String dataString) throws Exception
{
// decode and decrypt the data
byte[] data = Base64.decode(dataString);
data = cipher.doFinal(data);
return new String(data);
}

public static void main(String[] args) throws Exception
{
System.out.println(decrypt("iMeOizw/O75tdjDSzXSlkUCGahuNYSvhc5oW/jKzV7+hS6eaxtWzbhcssgAd4ygxGbBL3gZxzxEVePRfLedFPqX/DAHMKSVbeCqbtE+1TtHjvIo46SReAahNANvDJnAXmCO2Bp4p+l4hGrTCAz9EXkhUQdel6AIc0DwJOSB0I+4="));
}
}


=============================
Results:
=============================
test



You can use this class to regenerate your new keys and secure your data. Simply replace the keys in the code and secure your data.

Happy Securing Data !!

1 comment:

Unknown said...

Hi @ All,

I got the sample from Sun Forum...

http://java.sun.com/developer/JDCTechTips/2004/tt0116.html

my the only missing question is: how can i get the q and p values to get N??

anyone out there who can give me a helping hand ?

with best regards,

eric_88888888