RSA Encryption Encode using Android Decrypt using apache codec Issue - java

1) I have a private key in a txt file
2) I have written a decrypt method
while running the decrypt method I am getting the below mentioned exception.
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Calendar;
import java.util.Random;
import javax.crypto.Cipher;
import android.util.Base64;
public static String decrypt(String inputString, byte[] keyBytes) {
String resultStr = null;
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "XXwerr" + num;
PrivateKey privateKey = null;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes);
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (Exception e) {
System.out.println("Exception privateKey::::::::::::::::: "
+ e.getMessage());
}
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
//Also tried
// Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, privateKey);
decodedBytes = c.doFinal(Base64.decode(inputString, Base64.NO_CLOSE));
} catch (Exception e) {
System.out.println("Exception privateKey1::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
if (decodedBytes != null) {
resultStr = new String(decodedBytes);
System.out.println("resultStr:::" + resultStr + ":::::");
resultStr = resultStr.replace(salt, "");
}
return resultStr;
}
Following is the main method
public static void main(String[] args) {
FileInputStream fileInputStream = null;
File file = new File("/Users/buta1/Downloads/private.txt");
byte[] bFile = new byte[(int) file.length()];
try {
// convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
// for (int i = 0; i < bFile.length; i++) {
// System.out.println((char)bFile[i]);
// }
decrypt("08F8CFE58F2E707C314F4D7894E0F1", bFile);
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
}
THE ENCRYPTION METHOD USED IS AS follows USING ANDROID Base64 class
public static String encrypt(String inputString, byte [] keyBytes)
{
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
//System.out.println("Day of month :::" + mDay);
String encryptedString = "";
Key publicKey = null;
try {
Random generator = new Random(mDay);
int num = (generator.nextInt() ) % 100;
String salt = "xx"+num;
inputString += salt;
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "+
e.getMessage());
}
// Encode the original data with RSA public key
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, publicKey);
encodedBytes = c.doFinal(inputString.getBytes());
encryptedString =
Base64.encodeToString(encodedBytes, Base64.NO_CLOSE);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "+
e.getMessage());
}
return encryptedString;
}
After using commons codec Base 64
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding ");
getting following error
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:365)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at RSAEncryption.decrypt(RSAEncryption.java:41)
at RSAEncryption.main(RSAEncryption.java:108)

I am assuming that you are trying to run Android code from inside your IDE with the android.jar on your classpath (e.g. by using the ADT Plugin in eclipse). Then this looks like "working as intended" (cf. https://code.google.com/p/android/issues/detail?id=33188).
The android.jar only contains stub implementations for all classes, because the intended way would be to run that code inside an emulator.
If you are trying to write code for Android and you find running the code inside an emulator to be too cumbersome, you could try Roboelectric, which basically replaces all those stubs with real implementations and allows you to run the code from inside your IDE.
On the other hand, if you are not trying to write code for Android you can simply replace android.util.Base64 with org.apache.commons.codec.binary.Base64 or java.util.Base64.Decoder (since Java 8).

Related

NTRU BouncyCastle

I am developing a Java application and I want to add a special encryption method - NTRU. Before that I used symmetric and asymmetric methods supplied by the bouncycastle provider however now I can't understand how works Post-Quantum algorithms in bouncycastle due to lack of any information on the network. Please help me implement NTRU text encryption code.
I tried using the light-weight API but it didn't work, my code refuses to do anything
This is a complete running example for NTRU, it is not a general encryption algorithm but a key exchange algorithm (KEM). To get this to work you need an actual Bouncy Castle lib available (I tested with BC verson 1.71 and 1.72).
It is taken from my Android app to test some Post Quantum Algorithms (PQC) with complete code here: https://github.com/MichaelsPlayground/PostQuantumCryptographyBc172
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
import org.bouncycastle.jcajce.spec.KEMExtractSpec;
import org.bouncycastle.jcajce.spec.KEMGenerateSpec;
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
import org.bouncycastle.pqc.legacy.crypto.ntru.NTRUEncryptionKeyGenerationParameters;
import org.bouncycastle.pqc.legacy.crypto.ntru.NTRUEncryptionKeyPairGenerator;
import org.bouncycastle.pqc.legacy.crypto.ntru.NTRUEncryptionParameters;
import org.bouncycastle.pqc.legacy.crypto.ntru.NTRUEncryptionPrivateKeyParameters;
import org.bouncycastle.pqc.legacy.crypto.ntru.NTRUEncryptionPublicKeyParameters;
import org.bouncycastle.pqc.legacy.crypto.ntru.NTRUEngine;
import org.bouncycastle.util.Arrays;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.KeyGenerator;
public class PqcNtruKem {
public static void main(String[] args) {
//Security.addProvider(new BouncyCastleProvider());
// we do need the regular Bouncy Castle file that includes the PQC provider
// get Bouncy Castle here: https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on
// tested with BC version 1.71
if (Security.getProvider("BCPQC") == null) {
Security.addProvider(new BouncyCastlePQCProvider());
}
System.out.println("PQC NTRU kem");
System.out.println("\n************************************\n" +
"* # # SERIOUS SECURITY WARNING # # *\n" +
"* This program is a CONCEPT STUDY *\n" +
"* for the algorithm *\n" +
"* NTRU [key exchange mechanism] *\n" +
"* The program is using an *\n" +
"* parameter set that I cannot *\n" +
"* check for the correctness of the *\n" +
"* output and other details *\n" +
"* *\n" +
"* DO NOT USE THE PROGRAM IN *\n" +
"* ANY PRODUCTION ENVIRONMENT *\n" +
"************************************");
// as there are 7 parameter sets available the program runs all of them
NTRUEncryptionKeyGenerationParameters[] ntruEncryptionKeyGenerationParameterSets = {
NTRUEncryptionKeyGenerationParameters.EES1087EP2,
NTRUEncryptionKeyGenerationParameters.EES1171EP1,
NTRUEncryptionKeyGenerationParameters.EES1499EP1,
NTRUEncryptionKeyGenerationParameters.APR2011_439,
NTRUEncryptionKeyGenerationParameters.APR2011_439_FAST,
NTRUEncryptionKeyGenerationParameters.APR2011_743,
NTRUEncryptionKeyGenerationParameters.APR2011_743_FAST,
};
// short name of the parameters for the summary print out
String[] ntruEncryptionKeyGenerationParameterNames = {
"EES1087EP2",
"EES1171EP1",
"EES1499EP1",
"APR2011_439",
"APR2011_439_FAST",
"APR2011_743",
"APR2011_743_FAST"
};
// statistics
int nrOfSpecs = ntruEncryptionKeyGenerationParameterSets.length;
String[] parameterSpecName = new String[nrOfSpecs];
int[] privateKeyLength = new int[nrOfSpecs];
int[] publicKeyLength = new int[nrOfSpecs];
int[] encryptedKeyLength = new int[nrOfSpecs];
boolean[] encryptionKeysEquals = new boolean[nrOfSpecs];
// data to encrypt is usually a 32 bytes long (randomly generated) AES key
String keyToEncryptString = "1234567890ABCDEF1122334455667788";
byte[] keyToEncrypt = keyToEncryptString.getBytes(StandardCharsets.UTF_8);
for (int i = 0; i < nrOfSpecs; i++) {
// generation of the NTRU key pair
NTRUEncryptionKeyGenerationParameters ntruEncryptionKeyGenerationParameters = ntruEncryptionKeyGenerationParameterSets[i];
String ntruParameterSpecName = ntruEncryptionKeyGenerationParameterNames[i];
parameterSpecName[i] = ntruParameterSpecName;
System.out.println("\nNTRU KEM with parameterset " + ntruParameterSpecName);
AsymmetricCipherKeyPair keyPair = generateNtruKeyPair(ntruEncryptionKeyGenerationParameters);
// get private and public key
AsymmetricKeyParameter privateKey = keyPair.getPrivate();
AsymmetricKeyParameter publicKey = keyPair.getPublic();
// storing the key as byte array
byte[] privateKeyByte = ((NTRUEncryptionPrivateKeyParameters) privateKey).getEncoded();
byte[] publicKeyByte = ((NTRUEncryptionPublicKeyParameters) publicKey).getEncoded();
System.out.println("\ngenerated private key length: " + privateKeyByte.length);
System.out.println("generated public key length: " + publicKeyByte.length);
privateKeyLength[i] = privateKeyByte.length;
publicKeyLength[i] = publicKeyByte.length;
// generate the keys from a byte array
NTRUEncryptionPrivateKeyParameters privateKeyLoad = getNtruPrivateKeyFromEncoded(privateKeyByte, ntruEncryptionKeyGenerationParameters);
NTRUEncryptionPublicKeyParameters publicKeyLoad = getNtruPublicKeyFromEncoded(publicKeyByte, ntruEncryptionKeyGenerationParameters);
// generate the encryption key and the encapsulated key
System.out.println("\nEncryption side: generate the encryption key");
byte[] encryptedKey = pqcNtruEncryptKey(publicKeyLoad, keyToEncrypt);
System.out.println("encrypted key length: " + encryptedKey.length
+ " key: " + bytesToHex(encryptedKey));
encryptedKeyLength[i] = encryptedKey.length;
System.out.println("\nDecryption side: receive the encrypted key and decrypt it to the decryption key");
byte[] decryptedKey = pqcNtruDecryptKey(privateKeyLoad, encryptedKey);
System.out.println("decryption key length: " + decryptedKey.length + " key: " + bytesToHex(decryptedKey));
boolean keysAreEqual = Arrays.areEqual(keyToEncrypt, decryptedKey);
System.out.println("decrypted key is equal to keyToEncrypt: " + keysAreEqual);
encryptionKeysEquals[i] = keysAreEqual;
}
System.out.println("\nTest results");
System.out.println("parameter spec name priKL pubKL encKL keyE");
for (int i = 0; i < nrOfSpecs; i++) {
System.out.format("%-20s%6d%8d%6d%6b%n", parameterSpecName[i], privateKeyLength[i], publicKeyLength[i], encryptedKeyLength[i], encryptionKeysEquals[i]);
}
System.out.println("Legend: priKL privateKey length, pubKL publicKey length, encKL encryption key length, keyE encryption keys are equal\n");
}
private static AsymmetricCipherKeyPair generateNtruKeyPair(NTRUEncryptionKeyGenerationParameters ntruEncryptionKeyGenerationParameters) {
NTRUEncryptionKeyPairGenerator ntruEncryptionKeyPairGenerator = new NTRUEncryptionKeyPairGenerator();
ntruEncryptionKeyPairGenerator.init(ntruEncryptionKeyGenerationParameters);
AsymmetricCipherKeyPair kp = ntruEncryptionKeyPairGenerator.generateKeyPair();
return kp;
}
private static byte[] pqcNtruEncryptKey(AsymmetricKeyParameter publicKey, byte[] keyToEncrypt) {
NTRUEngine ntru = new NTRUEngine();
ntru.init(true, publicKey);
try {
return ntru.processBlock(keyToEncrypt, 0, keyToEncrypt.length);
} catch (InvalidCipherTextException e) {
e.printStackTrace();
return null;
}
}
private static byte[] pqcNtruDecryptKey(AsymmetricKeyParameter privateKey, byte[] encryptedKeyToDecrypt) {
NTRUEngine ntru = new NTRUEngine();
ntru.init(false, privateKey);
try {
return ntru.processBlock(encryptedKeyToDecrypt, 0, encryptedKeyToDecrypt.length);
} catch (InvalidCipherTextException e) {
e.printStackTrace();
return null;
}
}
public static SecretKeyWithEncapsulation pqcGenerateNtruEncryptionKey(PublicKey publicKey) {
KeyGenerator keyGen = null;
try {
keyGen = KeyGenerator.getInstance("Frodo", "BCPQC");
keyGen.init(new KEMGenerateSpec((PublicKey) publicKey, "AES"), new SecureRandom());
SecretKeyWithEncapsulation secEnc1 = (SecretKeyWithEncapsulation) keyGen.generateKey();
return secEnc1;
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
return null;
}
}
public static byte[] pqcGenerateFrodoDecryptionKey(PrivateKey privateKey, byte[] encapsulatedKey) {
KeyGenerator keyGen = null;
try {
keyGen = KeyGenerator.getInstance("Frodo", "BCPQC");
keyGen.init(new KEMExtractSpec((PrivateKey) privateKey, encapsulatedKey, "AES"), new SecureRandom());
SecretKeyWithEncapsulation secEnc2 = (SecretKeyWithEncapsulation) keyGen.generateKey();
return secEnc2.getEncoded();
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
return null;
}
}
private static NTRUEncryptionPrivateKeyParameters getNtruPrivateKeyFromEncoded(byte[] encodedKey, NTRUEncryptionKeyGenerationParameters ntruEncryptionKeyGenerationParameters) {
NTRUEncryptionParameters ntruEncryptionParameters = ntruEncryptionKeyGenerationParameters.getEncryptionParameters();
try {
return new NTRUEncryptionPrivateKeyParameters(encodedKey, ntruEncryptionParameters);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static NTRUEncryptionPublicKeyParameters getNtruPublicKeyFromEncoded(byte[] encodedKey, NTRUEncryptionKeyGenerationParameters ntruEncryptionKeyGenerationParameters) {
NTRUEncryptionParameters ntruEncryptionParameters = ntruEncryptionKeyGenerationParameters.getEncryptionParameters();
return new NTRUEncryptionPublicKeyParameters(encodedKey, ntruEncryptionParameters);
}
private static PublicKey getFrodoPublicKeyFromEncoded(byte[] encodedKey) {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory keyFactory = null;
try {
keyFactory = KeyFactory.getInstance("Frodo", "BCPQC");
return keyFactory.generatePublic(x509EncodedKeySpec);
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeySpecException e) {
e.printStackTrace();
return null;
}
}
private static String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
return result.toString();
}
}

Java Password based Encryption decrypt throwing errors

I am trying to write a program that will encrypt a file based on a password the user enters when calling the program. The salt of the password should be included in the file. I believe the program is encrypting the file properly but when I go to decrypt the file the program throws
java.security.InvalidAlgorithmParameterException: Missing parameter type: IV expected.
I am not sure as to why this would be the case as I am not generating an IV as such. To call the program it is enc "password" fileToEncrypt.txt destinationFile.enc.
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.HexFormat;
import java.util.logging.Logger;
public class FileEncryptor {
private static final Logger LOG = Logger.getLogger(FileEncryptor.class.getSimpleName());
private static final String ALGORITHM = "AES";
private static final String CIPHER = "AES/CBC/PkCS5PADDING";
public static void main(String[] args) {
if (args.length == 4) {
if (args[0].equals("enc") || args[0].equals("dec")) {
try {
if (args[0].equals("enc")) {
SecureRandom sr = new SecureRandom();
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
byte[] salt = new byte[16];
sr.nextBytes(salt);
int count = 1000;
pbeParamSpec = new PBEParameterSpec(salt, count);
char[] password = args[1].toCharArray();
pbeKeySpec = new PBEKeySpec(password);
keyFac = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_256");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
Cipher pbeCipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_256");
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
if (encrypt(pbeCipher, args[2], args[3],salt)) {
LOG.info("Encryption finished, saved at " + args[3]);
}
} else {
PBEKeySpec pbeKeySpec;
SecretKeyFactory keyFac;
char[] password = args[1].toCharArray();
pbeKeySpec = new PBEKeySpec(password);
keyFac = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_256");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
Cipher pbeCipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_256");
if (decrypt(pbeCipher, pbeKey, args[2], args[3])) {
LOG.info("Decryption complete, open " + args[3]);
}
}
} catch (Exception e) {
exceptionHandle(e);
}
} else {
errorHandle("Please call encrypt or decrypt");
}
} else {
errorHandle("Please call program with 4 arguments");
}
}
/**
* Method to encrypt a file with the Key and IV generated by the program and write the results to a
* new file.
*
* #param cipher cipher generated by the program early
* #param input name of the file to be encrypted
* #param output name of the new file after encryption
* #return boolean if encryption was successful or not.
*/
public static boolean encrypt(Cipher cipher, String input, String output,byte[] salt) {
LOG.info("File to be Encrypted: " + input);
try (FileInputStream in = new FileInputStream(input);
FileOutputStream out = new FileOutputStream(output);
CipherOutputStream encryptedOutputStream = new CipherOutputStream(out, cipher)) {
out.write(salt);
byte[] buffer = new byte[1024];
int nread;
while ((nread = in.read(buffer)) > 0) {
encryptedOutputStream.write(buffer, 0, nread);
}
encryptedOutputStream.flush();
} catch (IOException e) {
exceptionHandle(e);
}
return true;
}
/**
* Method to decrypt a file with the Key inputted by the user and IV stored in the file. Then write the results to a
* new file.
*
* #param cipher cipher generated by the program early based on key and IV provided.
* #param input name of the file to be decrypted
* #param output name of the new file after decryption
* #return boolean if decryption was successful or not
*/
public static boolean decrypt(Cipher cipher,SecretKey pbeKey, String input, String output) {
int count = 1000;
try (FileInputStream in = new FileInputStream(input);
CipherInputStream cipherInputStream = new CipherInputStream(in, cipher);
FileOutputStream out = new FileOutputStream(output)) {
byte[] salt = new byte[16];
in.read(salt);
byte[] buffer = new byte[1024];
cipher.init(Cipher.DECRYPT_MODE, pbeKey,new PBEParameterSpec(salt, count));
int nread;
while ((nread = cipherInputStream.read(buffer)) > 0) {
out.write(buffer, 0, nread);
}
out.flush();
} catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException ex) {
ex.printStackTrace();
exceptionHandle(ex);
return false;
}
return true;
}
/**
* Methods prints a message to the console to let the user know what mistakes they made when running the program.
*
* #param message to be printed to the console.
*/
public static void errorHandle(String message) {
System.out.println(message);
}
/**
* Program prints a message to the user to let them know what went wrong in the program based on what exception
* was thrown early in the program and give them clear understanding of what went wrong.
*
* #param e Exception caught be the program
*/
public static void exceptionHandle(Exception e) {
if(e.getClass() == BadPaddingException.class){
System.out.println("hello");
LOG.info("Please input correct key. " + e.getMessage());
}
if (e.getClass() == FileNotFoundException.class) {
LOG.info("Please call enc or dec with an existing file. " + e.getMessage());
}
if (e.getClass() == InvalidKeyException.class) {
LOG.info("Please put correct Algorithm. " + e.getMessage());
}
if (e.getClass() == NoSuchAlgorithmException.class) {
LOG.info("Please put correct Cipher " + e.getMessage());
}
if (e.getClass() == InvalidAlgorithmParameterException.class) {
LOG.info("Please put correct IV length. " + e.getMessage());
}
if (e.getClass() == IllegalArgumentException.class) {
LOG.info("Please check length Key and IV. " + e.getMessage());
}
if (e.getClass() == NoSuchPaddingException.class) {
LOG.info("Please check Padding. " + e.getMessage());
}
}
public static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
}

JAR file works as expected on Linux, throws exceptions on Windows

I have written a basic text encryption program in Java. (Yes, I'm aware that it uses ECB...)
My program works fine on Linux. I complied it as a JAR file, and that also works fine on Linux. The problem is that when I run the file on Windows, it will throw an exception while decrypting the same text with the same key that worked on Ubuntu.
I have no idea where to start debugging or even what search terms to use on Google. I am at a complete loss. I thought Java was cross-platform.
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class Application
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String textToEncrypt = "Hello World";
String textToDecrypt;
String textToDecryptAscii;
String result;
int operation;
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//String key = "Bar12345Bar12345"; // 128 bit key
String key = null;
BASE64Encoder asciiEncoder = new BASE64Encoder();
BASE64Decoder asciiDecoder = new BASE64Decoder();
System.out.printf("Enter:\n1 for encryption\n2 for decryption\n\nChoice: ");
operation = input.nextInt();
input.nextLine();
if (operation == 1)
{
try
{
System.out.print("Enter a 128-bit key to be used for encryption: ");
key = input.nextLine();
if(key.length() != 16)
{
while(key.length() != 16)
{
System.out.print("You need to enter a *128-bit* key: ");
key = input.nextLine();
}
}
System.out.printf("\n---------\n\nText to encrypt: ");
textToEncrypt = input.nextLine();
//Create key and cipher
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
//Cipher cipher = Cipher.getInstance("AES");
//encrypt the text
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encrypted = cipher.doFinal(textToEncrypt.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b: encrypted)
{
sb.append((char)b);
}
// the encrypted String
String enc = sb.toString();
//System.out.println("encrypted:" + enc);
String asciiEncodedEncryptedResult = asciiEncoder.encodeBuffer(enc.getBytes());
asciiEncodedEncryptedResult = asciiEncodedEncryptedResult.replace("\n", "").replace("\r", "");
System.out.println("Encrypted text: " + asciiEncodedEncryptedResult);
//System.out.printf("\n------------------------------\nDecrypted text: " + asciiEncodedEncryptedResult + "\n------------------------------\n\n\n");
}
catch(Exception e)
{
e.printStackTrace();
}
}
else if (operation == 2)
{
System.out.printf("\n---------\n\nText to decrypt: ");
textToDecryptAscii = input.nextLine();
System.out.print("Enter the 128-bit decryption key: ");
key = input.nextLine();
if(key.length() != 16)
{
while(key.length() != 16)
{
System.out.print("You need to enter a *128-bit* key: ");
key = input.nextLine();
}
}
byte[] decodedBytes = null;
try
{
decodedBytes = asciiDecoder.decodeBuffer(textToDecryptAscii);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//System.out.println("decodedBytes " + new String(decodedBytes));
textToDecrypt = new String(decodedBytes);
//Convert the string to byte array
//for decryption
byte[] bb = new byte[textToDecrypt.length()];
for (int i=0; i<textToDecrypt.length(); i++)
{
bb[i] = (byte) textToDecrypt.charAt(i);
}
//decrypt the text
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
try
{
cipher.init(Cipher.DECRYPT_MODE, aesKey);
}
catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String decrypted = null;
try
{
decrypted = new String(cipher.doFinal(bb));
}
catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.printf("\n------------------------------\nDecrypted text: " + decrypted + "\n------------------------------\n\n\n");
}
}
}
I've seen this before doing encryption because of the differences in CRLF between Linux/Unix and Windows. The two operating systems see Carriage Return Line Feed and Line Feed quite differently.
You may need to compile your code into a jar file using Ant and the fixcrlf step :
<fixcrlf
srcdir="${dir.prj.work}"
eol="dos"
includes="**/*"
/>
Also, it may not be your code...If the text your are feeding in doesn't have the correct CRLF encoded, your encryption will fail as well.
Edit :
For what it's worth, below is an abridged version of your code, that skips operations...it just takes in the key, does the encryption then turns around and decrypts all in one stream...I got tired of inputting the same operations, same keys, etc...
Anyway, the following code works without the BASE64 Encoder, Decoder...I couldn't get it to work with the BASE64. Although output from tests showed the BASE64 "seemed" to be working as I was getting what looked like the correct encrypted text after the Decoder, but it still continued to throw the error.
However, if you take the BASE64 Encoder and Decoder out of the picture, the encryption/decryption works fine...Also, I added a few key .trim() in there as I saw invisible CRLF being introduced in the String components.
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class Application {
public Application() {
// TODO Auto-generated constructor stub
}
public static void main ( String[] args ) {
Scanner input = new Scanner(System.in);
String textToEncrypt = "Hello World";
String textToDecrypt;
String textToDecryptAscii;
String result;
int operation;
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
e1.printStackTrace();
}
//String key = "Bar12345Bar12345"; // 128 bit key
String key = null;
//byte[] key = null;
//BASE64Encoder asciiEncoder = new BASE64Encoder();
//BASE64Decoder asciiDecoder = new BASE64Decoder();
//System.out.printf("Enter:\n1 for encryption\n2 for decryption\n\nChoice: ");
//operation = input.nextInt();
//input.nextLine();
try {
System.out.print("Enter a 128-bit key to be used for encryption: ");
key = input.nextLine();
if ( key.length() != 16 ) {
while ( key.length() != 16 ) {
System.out.print("You need to enter a *128-bit* key: ");
key = input.nextLine();
}
}
System.out.println ( "128-bit encryption key.......................["+key+"] length ["+key.length ()+"]");
System.out.printf ( "Text to encrypt..............................[");
//System.out.printf("\n---------\n\nText to encrypt: ");
textToEncrypt = input.nextLine();
System.out.println ( "Text to encrypt..............................["+textToEncrypt+"] length ["+textToEncrypt.length ()+"]");
//Create key and cipher
Key aesKey = new SecretKeySpec(key.trim().getBytes(), "AES");
//Cipher cipher = Cipher.getInstance("AES");
//encrypt the text
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encrypted = cipher.doFinal(textToEncrypt.getBytes ());
StringBuilder sb = new StringBuilder();
for (byte b: encrypted) {
sb.append((char)b);
}
// the encrypted String
String enc = sb.toString();
System.out.println ( "Encrypted text...............................["+enc+"] length ["+enc.length ()+"]");
//System.out.println("encrypted:" + enc);
//String asciiEncodedEncryptedResult = asciiEncoder.encodeBuffer(enc.getBytes()).trim ();
String asciiEncodedEncryptedResult = enc.trim ();
System.out.println ( "Encoded text.................................["+asciiEncodedEncryptedResult+"] length ["+asciiEncodedEncryptedResult.length ()+"]");
//asciiEncodedEncryptedResult = asciiEncodedEncryptedResult.replace("\n", "").replace("\r", "");
asciiEncodedEncryptedResult = asciiEncodedEncryptedResult.trim ();
System.out.println ( "Encrypted text...............................["+asciiEncodedEncryptedResult+"] length ["+asciiEncodedEncryptedResult.length ()+"]");
//byte[] decodedBytes = null;
//try {
// decodedBytes = asciiDecoder.decodeBuffer(asciiEncodedEncryptedResult);
//}
//catch (IOException e1) {
// e1.printStackTrace();
//}
//System.out.println ( "Decoded Bytes................................["+decodedBytes+"] length ["+decodedBytes.length+"]");
//textToDecrypt = new String(decodedBytes);
textToDecrypt = asciiEncodedEncryptedResult;
System.out.println ( "Text to Decrypt..............................["+textToDecrypt+"] length ["+textToDecrypt.length()+"]");
//Convert the string to byte array
//for decryption
byte[] bb = new byte[textToDecrypt.length()];
for ( int i=0; i<textToDecrypt.length(); i++ ) {
bb[i] = (byte) textToDecrypt.charAt(i);
}
//decrypt the text
//Key aesKey = null;
String decrypted = null;
try {
//aesKey = new SecretKeySpec(key.trim ().getBytes (), "AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
decrypted = new String(cipher.doFinal(bb));
}
catch (InvalidKeyException e) {
e.printStackTrace();
}
catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
catch (BadPaddingException e) {
e.printStackTrace();
}
catch ( Exception ltheXcp ) {
ltheXcp.printStackTrace ();
}
if ( decrypted != null ) {
System.out.println ( "Decrypted text...............................["+decrypted+"] length ["+decrypted.length ()+"]");
}
else {
System.out.println ( "Decrypted text...............................["+decrypted+"] length []");
}
}
catch ( Exception ltheXcp ) {
ltheXcp.printStackTrace ();
}
}
}
Sample output :
Enter a 128-bit key to be used for encryption: aaaaaaaaaaaaaaaa
128-bit encryption key.......................[aaaaaaaaaaaaaaaa] length [16]
Text to encrypt..............................[adymlincoln
Text to encrypt..............................[adymlincoln] length [11]
Encrypted text...............................[\_i8`???R????] length [16]
Encoded text.................................[\_i8`???R????] length [16]
Encrypted text...............................[\_i8`???R????] length [16]
Text to Decrypt..............................[\_i8`???R????] length [16]
Decrypted text...............................[adymlincoln] length [11]
Bottom line, there is "something" in the BASE64 Encoder/Decoder that is causing the decryption to fail...It's changing the bitwise characters in some fashion that I couldn't see using System.out.println()...perhaps a Hexidecimal output might show what...

Android Base64 Encoding and Apache codec decoding

We are using following method for encoding a string using ANDROID Base64.NO_CLOSE
public static String encrypt(String inputString, byte[] keyBytes) {
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
// System.out.println("Day of month :::" + mDay);
String encryptedString = "";
Key publicKey = null;
try {
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "WEER563784" + num;
inputString += salt;
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
// Encode the original data with RSA public key
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, publicKey);
encodedBytes = c.doFinal(inputString.getBytes());
encryptedString = Base64.encodeToString(encodedBytes,
Base64.NO_CLOSE);
System.out.println(encryptedString);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
return encryptedString;
}
The generated encrypted string is being decrypted outside Android app using following method
public static String decrypt(String inputString, byte[] keyBytes) {
String resultStr = null;
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "qqq" + num;
PrivateKey privateKey = null;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes);
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (Exception e) {
System.out.println("Exception privateKey::::::::::::::::: "
+ e.getMessage());
}
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.DECRYPT_MODE, privateKey);
// decodedBytes = c.doFinal(Base64.decodeBase64(inputString));
decodedBytes = c.doFinal(Base64InputStream());
} catch (Exception e) {
System.out.println("Exception privateKey1::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
if (decodedBytes != null) {
resultStr = new String(decodedBytes);
System.out.println("resultStr:::" + resultStr + ":::::");
resultStr = resultStr.replace(salt, "");
}
return resultStr;
}
We are getting following exceptions
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:365)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at RSAEncryption.decrypt(RSAEncryption.java:41)
at RSAEncryption.main(RSAEncryption.java:108)
So the questions are
1) Is it possible to decrypt the encrypted string using ANDROID Base64.NO_CLOSE, outside Android, i mean directly in the IDE?
2) In one of post I found that string encrypted using ANDROID Base64.NO_WRAP can be decrypted outside Android env, is this a correct understanding?
Thanks a lot for you your help in advance.
Regards,
Amit
The issue is fixed...
while decrypting we need to use RSA/ECB/NoPadding
Basically when we encrypted the value using RSA in Android device decryption in a separate standalone Java env should use RSA/ECB/NoPadding in the Cipher.
Android Encryption Code:
public static String encrypt(String inputString, byte[] keyBytes) {
Calendar cal = Calendar.getInstance();
int mDay = cal.get(Calendar.DAY_OF_MONTH);
// System.out.println("Day of month :::" + mDay);
String encryptedString = "";
Key publicKey = null;
try {
Random generator = new Random(mDay);
int num = (generator.nextInt()) % 100;
String salt = "MNSadm563784" + num;
//inputString += salt;
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
// Encode the original data with RSA public key
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.ENCRYPT_MODE, publicKey);
encodedBytes = c.doFinal(inputString.getBytes());
encryptedString = Base64.encodeToString(encodedBytes,
Base64.NO_CLOSE);
System.out.print("-----??"+encryptedString+"??-------");
} catch (Exception e) {
System.out.println("Exception rsaEncrypt::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
return encryptedString;
}
Server Decryption code:
public static String decrypt(String inputString, byte[] keyBytes) {
String resultStr = null;
// Calendar cal = Calendar.getInstance();
// int mDay = cal.get(Calendar.DAY_OF_MONTH);
// Random generator = new Random(mDay);
// int num = (generator.nextInt()) % 100;
// String salt = "MNSadm563784" + num;
PrivateKey privateKey = null;
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
keyBytes);
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (Exception e) {
System.out.println("Exception privateKey::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("RSA/ECB/NoPadding");
// Cipher c = Cipher.getInstance("RSA");
c.init(Cipher.DECRYPT_MODE, privateKey);
decodedBytes = c.doFinal(Base64.decodeBase64(inputString));
// decodedBytes = c.doFinal(Base64InputStream());
} catch (Exception e) {
System.out.println("Exception privateKey1::::::::::::::::: "
+ e.getMessage());
e.printStackTrace();
}
if (decodedBytes != null) {
resultStr = new String(decodedBytes);
System.out.println("resultStr:::" + resultStr + ":::::");
// resultStr = resultStr.replace(salt, "");
}
return resultStr;
}

rsa with digital signature coding in java

I was running a code for rsa with digital signature on netbeans but got the following error :
Exception caught
java.io.FileNotFoundException: \org\owasp\crypto\testkeystore.ks (The system cannot find the path specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:120)
at java.io.FileInputStream.(FileInputStream.java:79)
at org.owasp.crypto.PublicKeyCryptography.main(PublicKeyCryptography.java:52)
BUILD SUCCESSFUL (total time: 0 seconds)
package org.owasp.crypto;
import java.security.*;
import java.security.cert.*;
import javax.crypto.*;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class PublicKeyCryptography {
public static void main(String[] args) {
SymmetricEncrypt encryptUtil = new SymmetricEncrypt();
String strDataToEncrypt = "Hello World";
byte[] byteDataToTransmit = strDataToEncrypt.getBytes();
// Generating a SecretKey for Symmetric Encryption
SecretKey senderSecretKey = SymmetricEncrypt.getSecret();
//1. Encrypt the data using a Symmetric Key
byte[] byteCipherText = encryptUtil.encryptData(byteDataToTransmit,senderSecretKey,"AES");
String strCipherText = new BASE64Encoder().encode(byteCipherText);
//2. Encrypt the Symmetric key using the Receivers public key
try{
// 2.1 Specify the Keystore where the Receivers certificate has been imported
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
char [] password = "testpwd".toCharArray();
java.io.FileInputStream fis = new java.io.FileInputStream("/org/owasp/crypto/testkeystore.ks");
ks.load(fis, password);
fis.close();
// 2.2 Creating an X509 Certificate of the Receiver
X509Certificate recvcert ;
MessageDigest md = MessageDigest.getInstance("MD5");
recvcert = (X509Certificate)ks.getCertificate("testrecv");
// 2.3 Getting the Receivers public Key from the Certificate
PublicKey pubKeyReceiver = recvcert.getPublicKey();
// 2.4 Encrypting the SecretKey with the Receivers public Key
byte[] byteEncryptWithPublicKey = encryptUtil.encryptData(senderSecretKey.getEncoded(),pubKeyReceiver,"RSA/ECB/PKCS1Padding");
String strSenbyteEncryptWithPublicKey = new BASE64Encoder().encode(byteEncryptWithPublicKey);
// 3. Create a Message Digest of the Data to be transmitted
md.update(byteDataToTransmit);
byte byteMDofDataToTransmit[] = md.digest();
String strMDofDataToTransmit = new String();
for (int i = 0; i < byteMDofDataToTransmit.length; i++){
strMDofDataToTransmit = strMDofDataToTransmit + Integer.toHexString((int)byteMDofDataToTransmit[i] & 0xFF) ;
}
// 3.1 Message to be Signed = Encrypted Secret Key + MAC of the data to be transmitted
String strMsgToSign = strSenbyteEncryptWithPublicKey + "|" + strMDofDataToTransmit;
// 4. Sign the message
// 4.1 Get the private key of the Sender from the keystore by providing the password set for the private key while creating the keys using keytool
char[] keypassword = "send123".toCharArray();
Key myKey = ks.getKey("testsender", keypassword);
PrivateKey myPrivateKey = (PrivateKey)myKey;
// 4.2 Sign the message
Signature mySign = Signature.getInstance("MD5withRSA");
mySign.initSign(myPrivateKey);
mySign.update(strMsgToSign.getBytes());
byte[] byteSignedData = mySign.sign();
// 5. The Values byteSignedData (the signature) and strMsgToSign (the data which was signed) can be sent across to the receiver
// 6.Validate the Signature
// 6.1 Extracting the Senders public Key from his certificate
X509Certificate sendercert ;
sendercert = (X509Certificate)ks.getCertificate("testsender");
PublicKey pubKeySender = sendercert.getPublicKey();
// 6.2 Verifying the Signature
Signature myVerifySign = Signature.getInstance("MD5withRSA");
myVerifySign.initVerify(pubKeySender);
myVerifySign.update(strMsgToSign.getBytes());
boolean verifySign = myVerifySign.verify(byteSignedData);
if (verifySign == false)
{
System.out.println(" Error in validating Signature ");
}
else
System.out.println(" Successfully validated Signature ");
// 7. Decrypt the message using Recv private Key to get the Symmetric Key
char[] recvpassword = "recv123".toCharArray();
Key recvKey = ks.getKey("testrecv", recvpassword);
PrivateKey recvPrivateKey = (PrivateKey)recvKey;
// Parsing the MessageDigest and the encrypted value
String strRecvSignedData = new String (byteSignedData);
String[] strRecvSignedDataArray = new String [10];
strRecvSignedDataArray = strMsgToSign.split("|");
int intindexofsep = strMsgToSign.indexOf("|");
String strEncryptWithPublicKey = strMsgToSign.substring(0,intindexofsep);
String strHashOfData = strMsgToSign.substring(intindexofsep+1);
// Decrypting to get the symmetric key
byte[] bytestrEncryptWithPublicKey = new BASE64Decoder().decodeBuffer(strEncryptWithPublicKey);
byte[] byteDecryptWithPrivateKey = encryptUtil.decryptData(byteEncryptWithPublicKey,recvPrivateKey,"RSA/ECB/PKCS1Padding");
// 8. Decrypt the data using the Symmetric Key
javax.crypto.spec.SecretKeySpec secretKeySpecDecrypted = new javax.crypto.spec.SecretKeySpec(byteDecryptWithPrivateKey,"AES");
byte[] byteDecryptText = encryptUtil.decryptData(byteCipherText,secretKeySpecDecrypted,"AES");
String strDecryptedText = new String(byteDecryptText);
System.out.println(" Decrypted data is " +strDecryptedText);
// 9. Compute MessageDigest of data + Signed message
MessageDigest recvmd = MessageDigest.getInstance("MD5");
recvmd.update(byteDecryptText);
byte byteHashOfRecvSignedData[] = recvmd.digest();
String strHashOfRecvSignedData = new String();
for (int i = 0; i < byteHashOfRecvSignedData.length; i++){
strHashOfRecvSignedData = strHashOfRecvSignedData + Integer.toHexString((int)byteHashOfRecvSignedData[i] & 0xFF) ;
}
// 10. Validate if the Message Digest of the Decrypted Text matches the Message Digest of the Original Message
if (!strHashOfRecvSignedData.equals(strHashOfData))
{
System.out.println(" Message has been tampered ");
}
}
catch(Exception exp)
{
System.out.println(" Exception caught " + exp);
exp.printStackTrace();
}
}
}
package org.owasp.crypto;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import sun.misc.BASE64Encoder;
/**
* #author Joe Prasanna Kumar
* This program provides the following cryptographic functionalities
* 1. Encryption using AES
* 2. Decryption using AES
* High Level Algorithm :
* 1. Generate a DES key (specify the Key size during this phase)
* 2. Create the Cipher
* 3. To Encrypt : Initialize the Cipher for Encryption
* 4. To Decrypt : Initialize the Cipher for Decryption
*/
public class SymmetricEncrypt {
String strDataToEncrypt = new String();
String strCipherText = new String();
String strDecryptedText = new String();
static KeyGenerator keyGen;
private static String strHexVal = "0123456789abcdef";
public static SecretKey getSecret(){
/**
* Step 1. Generate an AES key using KeyGenerator
* Initialize the keysize to 128
*
*/
try{
keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
}
catch(Exception exp)
{
System.out.println(" Exception inside constructor " +exp);
}
SecretKey secretKey = keyGen.generateKey();
return secretKey;
}
/**
* Step2. Create a Cipher by specifying the following parameters
* a. Algorithm name - here it is AES
*/
public byte[] encryptData(byte[] byteDataToEncrypt, Key secretKey, String Algorithm) {
byte[] byteCipherText = new byte[200];
try {
Cipher aesCipher = Cipher.getInstance(Algorithm);
/**
* Step 3. Initialize the Cipher for Encryption
*/
if(Algorithm.equals("AES")){
aesCipher.init(Cipher.ENCRYPT_MODE,secretKey,aesCipher.getParameters());
}
else if(Algorithm.equals("RSA/ECB/PKCS1Padding")){
aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);
}
/**
* Step 4. Encrypt the Data
* 1. Declare / Initialize the Data. Here the data is of type String
* 2. Convert the Input Text to Bytes
* 3. Encrypt the bytes using doFinal method
*/
byteCipherText = aesCipher.doFinal(byteDataToEncrypt);
strCipherText = new BASE64Encoder().encode(byteCipherText);
}
catch (NoSuchAlgorithmException noSuchAlgo)
{
System.out.println(" No Such Algorithm exists " + noSuchAlgo);
}
catch (NoSuchPaddingException noSuchPad)
{
System.out.println(" No Such Padding exists " + noSuchPad);
}
catch (InvalidKeyException invalidKey)
{
System.out.println(" Invalid Key " + invalidKey);
}
catch (BadPaddingException badPadding)
{
System.out.println(" Bad Padding " + badPadding);
}
catch (IllegalBlockSizeException illegalBlockSize)
{
System.out.println(" Illegal Block Size " + illegalBlockSize);
illegalBlockSize.printStackTrace();
}
catch (Exception exp)
{
exp.printStackTrace();
}
return byteCipherText;
}
/**
* Step 5. Decrypt the Data
* 1. Initialize the Cipher for Decryption
* 2. Decrypt the cipher bytes using doFinal method
*/
public byte[] decryptData(byte[] byteCipherText, Key secretKey, String Algorithm) {
byte[] byteDecryptedText = new byte[200];
try{
Cipher aesCipher = Cipher.getInstance(Algorithm);
if(Algorithm.equals("AES")){
aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());
}
else if(Algorithm.equals("RSA/ECB/PKCS1Padding")){
aesCipher.init(Cipher.DECRYPT_MODE,secretKey);
}
byteDecryptedText = aesCipher.doFinal(byteCipherText);
strDecryptedText = new String(byteDecryptedText);
}
catch (NoSuchAlgorithmException noSuchAlgo)
{
System.out.println(" No Such Algorithm exists " + noSuchAlgo);
}
catch (NoSuchPaddingException noSuchPad)
{
System.out.println(" No Such Padding exists " + noSuchPad);
}
catch (InvalidKeyException invalidKey)
{
System.out.println(" Invalid Key " + invalidKey);
invalidKey.printStackTrace();
}
catch (BadPaddingException badPadding)
{
System.out.println(" Bad Padding " + badPadding);
badPadding.printStackTrace();
}
catch (IllegalBlockSizeException illegalBlockSize)
{
System.out.println(" Illegal Block Size " + illegalBlockSize);
illegalBlockSize.printStackTrace();
}
catch (InvalidAlgorithmParameterException invalidParam)
{
System.out.println(" Invalid Parameter " + invalidParam);
}
return byteDecryptedText;
}
public static byte[] convertStringToByteArray(String strInput) {
strInput = strInput.toLowerCase();
byte[] byteConverted = new byte[(strInput.length() + 1) / 2];
int j = 0;
int interimVal;
int nibble = -1;
for (int i = 0; i < strInput.length(); ++i) {
interimVal = strHexVal.indexOf(strInput.charAt(i));
if (interimVal >= 0) {
if (nibble < 0) {
nibble = interimVal;
} else {
byteConverted[j++] = (byte) ((nibble << 4) + interimVal);
nibble = -1;
}
}
}
if (nibble >= 0) {
byteConverted[j++] = (byte) (nibble << 4);
}
if (j < byteConverted.length) {
byte[] byteTemp = new byte[j];
System.arraycopy(byteConverted, 0, byteTemp, 0, j);
byteConverted = byteTemp;
}
return byteConverted;
}
public static String convertByteArrayToString(byte[] block) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < block.length; ++i) {
buf.append(strHexVal.charAt((block[i] >>> 4) & 0xf));
buf.append(strHexVal.charAt(block[i] & 0xf));
}
return buf.toString();
}
}
Your exception is caused because you've passed a non-existent file path to the FileInputStream constructor:
... = FileInputStream("/org/owasp/crypto/testkeystore.ks")
Make sure the path you provide is a valid relative or absolute path.

Categories

Resources