banner ad

Encryption Using Rsa Algorithm in Java

Encryption Using Rsa Algorithm in Java

Encryption using RSA algorithm in java

 

Introduction

In this article I will provide you an approach of using RSA algorithm for long String. As you know that RSA algorithm is limited 117 bytes, long strings can not be encrypted or decrypted. However it is possible to break the bytes into several chunks and then to encrypt or decrypt the contents. This algorithm is used for asymmetric cryptography. For asymmetric cryptography, you can click this link.

 

Technicalities

In this article I provide below the complete example for encryption and decryption of long strings. If you use the method of Cipher class ie.doFinal( byte[] bytesString), it will throw exception that it can be encrypted for more than 117 bytes for RSA.  But in the real application, you may not be sure about the length of the String you want to encrypt or decrypt. In this case you have to break the bytes and then to encrypt it. Please refer to the

Following complete example.

 

Complete example

 

Class name : SecurityUtil.java

 

package com.dds.core.security;

 

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Security;

import java.security.spec.EncodedKeySpec;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

 

import javax.crypto.Cipher;

 

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

 

import com.sun.crypto.provider.SunJCE;

 

/**This is a utility class which provides

 * convenient method for security. This

 * class provides the way where you can

 * encrypt and decrypt the String having

 * more than 117 bytes for RSA algorithm

 * which is an asymmetric one.

 * @author Debadatta Mishra(PIKU)

 *

 */

public class SecurityUtil {

            /**

             * Object of type {@link KeyPair}

             */

            private KeyPair keyPair;

            /**

             * String variable which denotes the algorithm

             */

            private static final String ALGORITHM = “RSA”;

            /**

             * varibale for the keysize

             */

            private static final int KEYSIZE = 1024;

 

            /**

             * Default constructor

             */

            public SecurityUtil() {

                        super();

                        Security.addProvider(new SunJCE());

            }

 

            /**

             * This method is used to generate

             * the key pair.

             */

            public void invokeKeys() {

                        try {

                                    KeyPairGenerator keypairGenerator = KeyPairGenerator

                                    .getInstance(ALGORITHM);

                                    keypairGenerator.initialize(KEYSIZE);

                                    keyPair = keypairGenerator.generateKeyPair();

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

            }

 

            /**This method is used to obtain the String

             * representation of the PublicKey.

             * @param publicKey of type {@link PublicKey}

             * @return PublicKey as a String

             */

            public String getPublicKeyString(PublicKey publicKey) {

                        return new BASE64Encoder().encode(publicKey.getEncoded());

            }

 

            /**This method is used to obtain the String

             * representation of the PrivateKey.

             * @param privateKey of type {@link PrivateKey}

             * @return PrivateKey as a String

             */

            public String getPrivateKeyString(PrivateKey privateKey) {

                        return new BASE64Encoder().encode(privateKey.getEncoded());

            }

 

            /**This method is used to obtain the

             * {@link PrivateKey} object from the

             * String representation.

             * @param key of type String

             * @return {@link PrivateKey}

             * @throws Exception

             */

            public PrivateKey getPrivateKeyFromString(String key) throws Exception {

                        PrivateKey privateKey = null;

                        try {

                                    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

                                    EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(

                                                            new BASE64Decoder().decodeBuffer(key));

                                    privateKey = keyFactory.generatePrivate(privateKeySpec);

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

                        return privateKey;

            }

 

            /**This method is used to obtain the {@link PublicKey}

             * from the String representation of the Public Key.

             * @param key of type String

             * @return {@link PublicKey}

             * @throws Exception

             */

            public PublicKey getPublicKeyFromString(String key) throws Exception {

                        PublicKey publicKey = null;

                        try {

                                    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);

                                    EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(

                                                            new BASE64Decoder().decodeBuffer(key));

                                    publicKey = keyFactory.generatePublic(publicKeySpec);

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

                        return publicKey;

            }

 

            /**This method is used to obtain the

             * encrypted contents from the original

             * contents by passing the {@link PublicKey}.

             * This method is useful when the byte is more

             * than 117.

             * @param text of type String

             * @param key of type {@link PublicKey}

             * @return encrypted value as a String

             * @throws Exception

             */

            public String getEncryptedValue(String text, PublicKey key)

            throws Exception {

                        String encryptedText;

                        try {

                                    byte[] textBytes = text.getBytes(“UTF8″);

                                    Cipher cipher = Cipher.getInstance(“RSA/ECB/PKCS1Padding”);

                                    cipher.init(Cipher.ENCRYPT_MODE, key);

 

                                    int textBytesChunkLen = 100;

                                    int encryptedChunkNum = (textBytes.length – 1) / textBytesChunkLen

                                    + 1;

 

                                    // RSA returns 128 bytes as output for 100 text bytes

                                    int encryptedBytesChunkLen = 128;

                                    int encryptedBytesLen = encryptedChunkNum * encryptedBytesChunkLen;

                                    System.out.println(“Encrypted bytes length——-”

                                                            + encryptedBytesChunkLen);

                                    // Define the Output array.

                                    byte[] encryptedBytes = new byte[encryptedBytesLen];

 

                                    int textBytesChunkIndex = 0;

                                    int encryptedBytesChunkIndex = 0;

 

                                    for (int i = 0; i

                                                if (i

                                                            encryptedBytesChunkIndex = encryptedBytesChunkIndex

                                                            + cipher.doFinal(textBytes, textBytesChunkIndex,

                                                                                    textBytesChunkLen, encryptedBytes,

                                                                                    encryptedBytesChunkIndex);

 

                                                            textBytesChunkIndex = textBytesChunkIndex

                                                            + textBytesChunkLen;

                                                } else {

                                                            cipher.doFinal(textBytes, textBytesChunkIndex,

                                                                                    textBytes.length – textBytesChunkIndex,

                                                                                    encryptedBytes, encryptedBytesChunkIndex);

                                                }

                                    }

                                    encryptedText = new BASE64Encoder().encode(encryptedBytes);

                        } catch (Exception e) {

                                    throw e;

                        }

                        return encryptedText;

            }

 

            /**This method is used to decrypt the contents.

             * This method is useful when the size of the

             * bytes is more than 117.

             * @param text of type String indicating the

             * encrypted contents.

             * @param key of type {@link PrivateKey}

             * @return decrypted value as a String

             */

            public String getDecryptedValue(String text, PrivateKey key) {

                        String result = null;

                        try {

                                    byte[] encryptedBytes = new BASE64Decoder().decodeBuffer(text);

                                    Cipher cipher = Cipher.getInstance(“RSA/ECB/PKCS1Padding”);

                                    cipher.init(Cipher.DECRYPT_MODE, key);

 

                                    int encryptedByteChunkLen = 128;

                                    int encryptedChunkNum = encryptedBytes.length

                                    / encryptedByteChunkLen;

                                    int decryptedByteLen = encryptedChunkNum * encryptedByteChunkLen;

                                    byte[] decryptedBytes = new byte[decryptedByteLen];

                                    int decryptedIndex = 0;

                                    int encryptedIndex = 0;

 

                                    for (int i = 0; i

                                                if (i

                                                            decryptedIndex = decryptedIndex

                                                            + cipher.doFinal(encryptedBytes, encryptedIndex,

                                                                                    encryptedByteChunkLen, decryptedBytes,

                                                                                    decryptedIndex);

                                                            encryptedIndex = encryptedIndex + encryptedByteChunkLen;

                                                } else {

                                                            decryptedIndex = decryptedIndex

                                                            + cipher.doFinal(encryptedBytes, encryptedIndex,

                                                                                    encryptedBytes.length – encryptedIndex,

                                                                                    decryptedBytes, decryptedIndex);

                                                }

                                    }

                                    result = new String(decryptedBytes).trim();

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

                        return result;

            }

 

            /**This method is used obtain the

             * {@link PublicKey}

             * @return {@link PublicKey}

             */

            public PublicKey getPublicKey() {

                        return keyPair.getPublic();

            }

 

            /**This method is used to obtain

             * the {@link PrivateKey}

             * @return {@link PrivateKey}

             */

            public PrivateKey getPrivateKey() {

                        return keyPair.getPrivate();

            }

}

 

The above class provides several useful methods for generation of Private key , Public Key and encryption of String and decryption of String.

 

Please refer to the following subordinate classes for the above class.

 

Class name : KeyGenerator.java

 

package com.dds.core.security;

 

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.util.Properties;

 

/**This class is used to generate the

 * Private and Public key and stores

 * them in files.

 * @author Debadatta Mishra(PIKU)

 *

 */

public class KeyGenerator {

            /**This method is used to obtain the

             * path of the keys directory where

             * Private and Public key files are

             * stored.

             * @return path of the keys directory

             */

            private static String getKeyFilePath() {

                        String keyDirPath = null;

                        try {

                                    keyDirPath = System.getProperty(“user.dir”) + File.separator

                                    + “keys”;

                                    File keyDir = new File(keyDirPath);

                                    if (!keyDir.exists())

                                                keyDir.mkdirs();

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

                        return keyDirPath;

            }

 

            /**

             * This method is used to generate the

             * Private and Public keys.

             */

            public static void generateKeys() {

                        Properties publicProp = new Properties();

                        Properties privateProp = new Properties();

                        try {

                                    OutputStream pubOut = new FileOutputStream(getKeyFilePath()

                                                            + File.separator + “public.key”);

                                    OutputStream priOut = new FileOutputStream(getKeyFilePath()

                                                            + File.separator + “private.key”);

 

                                    SecurityUtil secureUtil = new SecurityUtil();

                                    secureUtil.invokeKeys();

 

                                    PublicKey publicKey = secureUtil.getPublicKey();

                                    PrivateKey privateKey = secureUtil.getPrivateKey();

 

                                    String publicString = secureUtil.getPublicKeyString(publicKey);

                                    String privateString = secureUtil.getPrivateKeyString(privateKey);

 

                                    publicProp.put(“key”, publicString);

                                    publicProp.store(pubOut, “Public Key Info”);

 

                                    privateProp.put(“key”, privateString);

                                    privateProp.store(priOut, “Private Key Info”);

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

            }

}

 

The above class is used to generate the Public and Private keys. It generates and stores them in different files called Public.key and Private.key. Please refer the test harness class for the above class.

 

Class name: TestKeyGenerator

 

import com.dds.core.security.KeyGenerator;

 

/**This is a testharness class

 * for the KeyGenerator class.

 * @author Debadatta Mishra(PIKU)

 *

 */

public class TestKeyGenerator {

      public static void main(String[] args) {

            KeyGenerator.generateKeys();

      }

 

}

If you run the above class, you will find a directory called keys in your root path of your application folder. In this folder you will find two files one is for Private Key information and another is for Public Key.

There is another class which is used to obtain the Private key and Public key information stored in the files.

 

Class name: KeyReader.java

 

package com.dds.core.security;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.security.PublicKey;

import java.util.Properties;

 

/**This class is used to read the

 * keys from the file.

 * @author Debadatta Mishra(PIKU)

 *

 */

public class KeyReader {

            /**This method is used to obtain the

             * string value of the Public Key

             * from the file.

             * @return String of {@link PublicKey}

             */

            public static String getPublicKeyString() {

                        String publicString = null;

                        try {

                                    Properties prop = new Properties();

                                    String publicKeyPath = System.getProperty(“user.dir”)

                                    + File.separator + “keys” + File.separator + “public.key”;

                                    InputStream in = new FileInputStream(publicKeyPath);

                                    prop.load(in);

                                    publicString = prop.getProperty(“key”);

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

                        return publicString;

            }

 

            /**This method is used to obtain the

             * String of Private Key from the file.

             * @return String of private key

             */

            public static String getPrivateKeyString() {

                        String publicString = null;

                        try {

                                    Properties prop = new Properties();

                                    String publicKeyPath = System.getProperty(“user.dir”)

                                    + File.separator + “keys” + File.separator + “private.key”;

                                    InputStream in = new FileInputStream(publicKeyPath);

                                    prop.load(in);

                                    publicString = prop.getProperty(“key”);

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

                        return publicString;

            }

}

 

This is a utility class to read the Public and Private keys from the files.

 

Now refer to the test harness class which makes encryption and decryption of String.

 

import java.security.PrivateKey;

import java.security.PublicKey;

 

import com.dds.core.security.KeyReader;

import com.dds.core.security.SecurityUtil;

 

/**

 * This is a test harness class for encryption and decryption.

 *

 * @author Debadatta Mishra(PIKU)

 *

 */

public class TestEncryption {

 

            public static void main(String[] args) {

                        String privateKeyString = KeyReader.getPrivateKeyString();

                        SecurityUtil securityUtil = new SecurityUtil();

                        String publicKeyString = KeyReader.getPublicKeyString();

                        try {

                                    PublicKey publicKey = securityUtil

                                    .getPublicKeyFromString(publicKeyString);

                                    PrivateKey privateKey = securityUtil

                                    .getPrivateKeyFromString(privateKeyString);

                                    String originalValue = “provide some very long string”;

 

                                    String encryptedValue = securityUtil.getEncryptedValue(

                                                            originalValue, publicKey);

                                    System.out.println(“EncryptedValue—–” + encryptedValue);

                                    String decryptedValue = securityUtil.getDecryptedValue(

                                                            encryptedValue, privateKey);

                                    System.out.println(“Original Value——” + decryptedValue);

 

                        } catch (Exception e) {

                                    e.printStackTrace();

                        }

            }

 

}

 

This test harness class is used to encrypt and decrypt the long string contents. You can also use the same method for file encryption and decryption. First you have to read the contents of a file as String and then you can apply method to encrypt it.

 

Conclusion

I hope that you will enjoy my article for this asymmetric cryptography for RSA. For asymmetric cryptography please refer to the link http://www.articlesbase.com/information-technology-articles/asymmetric-cryptography-in-java-438155.html. If you find any problems or errors, please feel free to send me a mail in the address debadattamishra@aol.com . This article is only meant for those who are new to java development. This article does not bear any commercial significance. Please provide me the feedback about this article

Debadatta Mishra – An agressive java developer with a difference

[random:50]More Information Technology Articles Articles

Related entry for this Post

Filed Under: Programming

Tags:

Total : 5 views

RSSComments (0)

Trackback URL

Leave a Reply




If you want a picture to show with your comment, go get a Gravatar.

WP SlimStat