RSA is an encryption algorithm using public key encryption. For more details about RSA, please Google "RSA Encryption".
This code is a complete implementation of RSA using Java. The code will
generate large random numbers. It will then ask the user to type in a
message and enrypt and decrypt the message using those random generated
public and private key.
Here is an example of the execution:
Enter Message: Welcome to Shaniur.Com
Starting KeyGenerator....
Value of 'e': 65129
Value of 'd': 8510969
Value of 'n': 10130801
KeyGenerator Completed.
Encryption with Private key.
using d -> Encryption = 287B95 2E72CE 80C833 4038B4 8AAC72
4A2553 2E72CE 73C909 59B3F9 8AAC72 73C909 5127B8 6CA18F
2A4B78 81DD50 22DB1C D53F0 7EE30A 77778A 441A2 8AAC72
4A2553
using e -> Message = Welcome to Shaniur.Com
Encryption with Public key.
using e -> Encryption = 314D8A 60FBB1 3DDFB9 27E7CB 7E0ED6
73B6C5 60FBB1 3DC379 F367D 7E0ED6 3DC379 6EDF47 29EF6D
48D7C 4C7B14 8139FF 8BD9E6 4FAF69 68B7D5 29A7C5 7E0ED6
73B6C5
using d -> Message = Welcome to Shaniur.Com
There are 3 files for this program:
- RSADriver.java (the driver file)
- KeyGenerator.java (this generates the large random prime numbers)
- MakeRSA.java (the code that encrypts and decrypts the message)
All the codes are commented.
RSADriver.java
/**
* FILE NAME : RSADriver.java
* Completed by : Shaniur Nabi - www.shaniur.com
*
* This is the source code for the driver class that calls the
* RSA class.
*
* The class has been defined as RSADriver
* Date Written : 06/10/2004.
*/
import java.io.*;
import java.math.BigInteger;
class RSADriver {
public static void main (String [] args) throws IOException {
BufferedReader stdin = new BufferedReader
(new InputStreamReader (System.in));
/**
* Local variables
*/
String allKeys[] = new String[5];
String message;
String eMessage;
String dMessage;
String messageBack;
String messageD;
String tempString;
int messageLen;
String e, d, n;
//BigInteger e, d, n;
System.out.print("Enter Message: ");
message = stdin.readLine();
messageLen = message.length();
String cryptArray[] = new String[messageLen];
System.out.println("Starting KeyGenerator....");
KeyGenerator keys = new KeyGenerator(16);
allKeys = keys.getKeys();
e = allKeys[0];
System.out.println("Value of 'e': " + e);
d = allKeys[1];
System.out.println("Value of 'd': " + d);
n = allKeys[4];
System.out.println("Value of 'n': " + n);
System.out.println("KeyGenerator Completed.");
MakeRSA rsa = new MakeRSA(allKeys[0], allKeys[1], allKeys[4]);
cryptArray = rsa.privateEncrypt(message, d, n);
dMessage = "";
System.out.println("\nEncryption with Private key.");
for (int i = 0; i < messageLen; i++) {
dMessage = dMessage + cryptArray[i] + " ";
}
System.out.print("using d -> Encryption = " + dMessage);
messageBack = rsa.publicDecrypt(dMessage, e, n);
System.out.println("\nusing e -> Message = " + messageBack);
messageBack = "";
cryptArray = rsa.publicEncrypt(message, e, n);
eMessage = "";
System.out.println("\nEncryption with Public key.");
for (int i = 0; i < messageLen; i++) {
eMessage = eMessage + cryptArray[i] + " ";
}
System.out.print("using e -> Encryption = " + eMessage);
messageBack = rsa.privateDecrypt(eMessage, d, n);
System.out.print("\nusing d -> Message = " + messageBack);
System.out.println();
}
}
KeyGenerator.java
/**
* FILE NAME : KeyGenerator.java
* Completed by : Shaniur Nabi - www.shaniur.com
*
* This is the source code for the KeyGenerator class that generates
* the keys and returns them as an array or string.
*
* Date Written : 06/10/2004.
*/
import java.math.*;
import java.math.BigInteger;
import java.security.SecureRandom;
public class KeyGenerator {
/**
* Local variables
*/
private BigInteger n;
private BigInteger d;
private BigInteger e;
private BigInteger m;
private BigInteger p;
private BigInteger q;
private BigInteger p1;
private BigInteger q1;
private String values[] = new String[5];
private int gcdVal;
private int bitLen;
/**
* Default constructor - Sets the number of bits
*/
public KeyGenerator(int noOfBits) {
bitLen = noOfBits;
}
/**
* generates all the p, q, e, d and n and returns them
* as an array of stings in the order:
* index[0] = e
* index[1] = d
* index[2] = p
* index[3] = q
* index[4] = n
*/
public String[] getKeys() {
/**
* This generates a unique random seed
*/
SecureRandom rnd = new SecureRandom();
/**
* p is generated here which is 12 bits and a prime number
*/
p = new BigInteger(bitLen - 4, 100, rnd);
p1 = p;
/**
* q is generated here which is 12 bits and a prime number
*/
q = new BigInteger(bitLen - 4, 100, rnd);
q1 = q;
/**
* The following method behaves as
* n = p * q;
*/
n = p.multiply(q);
/**
* The following method behaves as
* p = p - 1;
*/
p1 = p.subtract(BigInteger.ONE);
/**
* The following method behaves as
* q = q - 1;
*/
q1 = q.subtract(BigInteger.ONE);
/**
* The following method behaves as
* m = p1 * q1;
*/
m = p1.multiply(q1);
/**
* e is generated here which is 16 bits and a prime number
*/
e = new BigInteger(bitLen, 100, rnd);
/**
* The following loop ensures that e is a coprime of m.
* Which means that the largest number that can exactly divide
* both e and m (their greatest common divisor, or gcd) is 1.
*/
while(m.gcd(e).intValue() > 1) {
e = e.add(new BigInteger("2"));
}
/**
* The following method generates the value of d
*/
d = e.modInverse(m);
/**
* The key values are converted to strings and stored in values array
* which is then returned.
*/
values[0] = e.toString();
values[1] = d.toString();
values[2] = p.toString();
values[3] = q.toString();
values[4] = n.toString();
return values;
}
}
MakeRSA.java
/**
* FILE NAME : MakeRSA.java
* Completed by : Shaniur Nabi - www.shaniur.com
*
* This is the source code for the MakeRSA class that encrypts and
* dycrypts the message based on the public key, private key and
* n values.
*
* The class has been defined as Driver
* Date Written : 06/10/2004.
*/
import java.math.*;
import java.math.BigInteger;
import java.util.*;
public class MakeRSA {
/**
* Local variables
*/
private String message;
private String tempMessage = "";
private String complete;
private int len;
private int msgVal;
private int noOfCharacters;
private int intVal;
private BigInteger e;
private BigInteger d;
private BigInteger n;
private BigInteger msg;
private BigInteger crypt;
private BigInteger decrypt;
private char tempChar;
/**
* Default constructor
*/
public MakeRSA() {
}
/**
* Constructor that takes in the 3 key values and sets them
* accordingly.
* Takes in the values in the order public key followed by private
* key and then the n value.
*/
public MakeRSA(String eVal, String dVal, String nVal) {
e = new BigInteger(eVal);
d = new BigInteger(dVal);
n = new BigInteger(nVal);
}
/**
* This method takes the plain text message and encrypts it character by
* character using the private key and returns the output in a string of
* hex values.
* The private key (d) and n values has to be passed in.
*/
public String[] privateEncrypt(String mesg, String dVal, String nVal) {
d = new BigInteger(dVal);
n = new BigInteger(nVal);
message = mesg;
tempMessage = "";
len = message.length();
String hexArray[] = new String[len];
int mArray[] = new int[len];
/**
* The loop begins to process character by character.
* By the end of each cycle of the loop a character will be encrypted
* to its HEX equivalent as a String and will be stored in hexArray
* which is then returned.
*/
for (int i = 0; i < len; i++){
/**
* All the characters are converted to ASCII (decimal) equivalent
* and placed in an array of integers.
*/
tempChar = message.charAt(i);
mArray[i] = (int)tempChar;
/**
* The int value is taken and converted to a string which is then
* converted to a BigInteger type.
*/
tempMessage = tempMessage + mArray[i];
msg = new BigInteger(tempMessage);
tempMessage = "";
/**
* The following line does the encryption by calling the modPow
* method of java.math.BigInteger class.
* Here the private key (d) and n value is used.
*/
crypt = msg.modPow(d, n);
/**
* The encrypted BigInteger is then converted to an Integer
*/
tempMessage = crypt.toString();
msgVal = Integer.parseInt(tempMessage);
/**
* The integer is then converted to its HEX equivalent by calling the
* toHexString method of java.lang.String class
*/
hexArray[i] = Integer.toHexString(msgVal);
hexArray[i] = hexArray[i].toUpperCase();
tempMessage = "";
}
return hexArray;
}
/**
* This method takes the plain text message and encrypts it character by
* character using the public key and returns the output in a string of
* hex values.
* The public key (e) and n values has to be passed in.
*/
public String[] publicEncrypt(String mesg, String eVal, String nVal) {
e = new BigInteger(eVal);
n = new BigInteger(nVal);
message = mesg;
tempMessage = "";
len = message.length();
String hexArray[] = new String[len];
int mArray[] = new int[len];
/**
* The loop begins to process character by character.
* By the end of each cycle of the loop a character will be encrypted
* to its HEX equivalent as a String and will be stored in hexArray
* which is then returned.
*/
for (int i = 0; i < len; i++){
/**
* All the characters are converted to ASCII (decimal) equivalent
* and placed in an array of integers.
*/
tempChar = message.charAt(i);
mArray[i] = (int)tempChar;
/**
* The int value is taken and converted to a string which is then
* converted to a BigInteger type.
*/
tempMessage = tempMessage + mArray[i];
msg = new BigInteger(tempMessage);
tempMessage = "";
/**
* The following line does the encryption by calling the modPow
* method of java.math.BigInteger class.
* Here the public key (e) and n value is used.
*/
crypt = msg.modPow(e, n);
/**
* The encrypted BigInteger is then converted to an Integer
*/
tempMessage = crypt.toString();
msgVal = Integer.parseInt(tempMessage);
/**
* The integer is then converted to its HEX equivalent by calling the
* toHexString method of java.lang.String class
*/
hexArray[i] = Integer.toHexString(msgVal);
hexArray[i] = hexArray[i].toUpperCase();
tempMessage = "";
}
return hexArray;
}
/**
* This method takes the encrypted message and decrypts it character by
* character using the private key and returns the output in a string.
* The private key (d) and n values has to be passed in.
*/
public String privateDecrypt(String mesg, String dVal, String nVal) {
d = new BigInteger(dVal);
n = new BigInteger(nVal);
message = mesg;
complete = "";
/**
* The encrypted string is tokenised and number of tokens are calculated.
*/
StringTokenizer characters = new StringTokenizer(message);
noOfCharacters = characters.countTokens();
/**
* The loop begins to process character by character.
* By the end of each cycle of the loop a encrypted character will be
* decrypted to plaim text as a String and will be stored in 'complete'
* which is then returned.
*/
for (int i = 0; i < noOfCharacters; i++) {
/**
* The decimal equivalent is generated and that is converted to
* equivalent BigInteger.
*/
tempMessage = characters.nextToken();
intVal = hex2Decimal(tempMessage);
tempMessage = "";
tempMessage = tempMessage + intVal;
msg = new BigInteger(tempMessage);
/**
* The following line does the decryption by calling the modPow
* method of java.math.BigInteger class.
* Here the private key (d) and n value is used.
*/
decrypt = msg.modPow(d, n);
/**
* Dycrypted BigInteger value of the plain text character is
* converted to integer (which is the decimal ASCII equivalent)
* and then the actual character is extracted from the ASCII value.
*/
tempMessage = decrypt.toString();
intVal = Integer.parseInt(tempMessage);
complete = complete + (char)intVal;
tempMessage = "";
}
return complete;
}
/**
* This method takes the encrypted message and decrypts it character by
* character using the public key and returns the output in a string.
* The public key (e) and n values has to be passed in.
*/
public String publicDecrypt(String mesg, String eVal, String nVal) {
e = new BigInteger(eVal);
n = new BigInteger(nVal);
message = mesg;
complete = "";
/**
* The encrypted string is tokenised and number of tokens are calculated.
*/
StringTokenizer characters = new StringTokenizer(message);
noOfCharacters = characters.countTokens();
/**
* The loop begins to process character by character.
* By the end of each cycle of the loop a encrypted character will be
* decrypted to plaim text as a String and will be stored in 'complete'
* which is then returned.
*/
for (int i = 0; i < noOfCharacters; i++) {
/**
* The decimal equivalent is generated and that is converted to
* equivalent BigInteger.
*/
tempMessage = characters.nextToken();
intVal = hex2Decimal(tempMessage);
tempMessage = "";
tempMessage = tempMessage + intVal;
msg = new BigInteger(tempMessage);
/**
* The following line does the decryption by calling the modPow
* method of java.math.BigInteger class.
* Here the public key (e) and n value is used.
*/
decrypt = msg.modPow(e, n);
/**
* Dycrypted BigInteger value of the plain text character is
* converted to integer (which is the decimal ASCII equivalent)
* and then the actual character is extracted from the ASCII value.
*/
tempMessage = decrypt.toString();
intVal = Integer.parseInt(tempMessage);
complete = complete + (char)intVal;
tempMessage = "";
}
return complete;
}
/**
* This method converts a hex string into a decimal
* number which is then used by other functions
* as all caluculation are performed using integers
*/
private int hex2Decimal (String message){
int intValue = 0, sizeOfString = 0, power = 0;
/**
* Each character is mapped and corressponding
* binary representations are stored in the
* binaryMessage String array of size sizeOfString
* which is the original size of messages string
*/
sizeOfString = message.length();
String binaryMessage[] = new String[sizeOfString];
/**
* Power stores the power of what each index will be
* raised to in order to perform the calculation
*/
power = ((4*sizeOfString)-1);
/**
* Each character of the original string is
* directly mapped to is binary repesentation
*/
for(int i=0; i<sizeOfString; i++){
switch(message.charAt(i)){
case '0':
binaryMessage[i] = "0000";
break;
case '1':
binaryMessage[i] = "0001";
break;
case '2':
binaryMessage[i] = "0010";
break;
case '3':
binaryMessage[i] = "0011";
break;
case '4':
binaryMessage[i] = "0100";
break;
case '5':
binaryMessage[i] = "0101";
break;
case '6':
binaryMessage[i] = "0110";
break;
case '7':
binaryMessage[i] = "0111";
break;
case '8':
binaryMessage[i] = "1000";
break;
case '9':
binaryMessage[i] = "1001";
break;
case 'A':
binaryMessage[i] = "1010";
break;
case 'B':
binaryMessage[i] = "1011";
break;
case 'C':
binaryMessage[i] = "1100";
break;
case 'D':
binaryMessage[i] = "1101";
break;
case 'E':
binaryMessage[i] = "1110";
break;
case 'F':
binaryMessage[i] = "1111";
break;
}
}
/**
* Each character is then raised to its appropriate power
* ie (2 ^ power) except for the last bit (signed bit)
* which is calculated as (-2 ^ 31)
*/
for(int i=0; i<sizeOfString; i++){
for(int j =0; j<4; j++){
if(binaryMessage[i].charAt(j) == '1'){
if (power == 31){
intValue = (intValue + ((int)Math.pow((double)-2,
(double)power)));
}
else{
intValue = (intValue + ((int)Math.pow((double)2,
(double)power)));
}
}
power--;
}
}
return intValue;
}
}
Add as favourites (7) | Quote this article on your site | Views: 1214
Powered by AkoComment Tweaked Special Edition v.1.4.6 AkoComment © Copyright 2004 by Arthur Konze - www.mamboportal.com All right reserved |