Kerry Girgich
Kerry Girgich

Reputation: 11

Decryption of Encrypted Secret Key and Encrypted String

So I think I have encrypted my secret key and String well but decryption is becoming the problem for me. Below is my code:

package ReadFileExample;


import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import java.security.KeyStore;



public class generatekey {


  static Cipher cipher;
  public static void main(String[] args) throws Exception {






    // generating a symmetric key using the AES algorithm
    KeyGenerator generator = KeyGenerator.getInstance("AES");
    // 128 bit key
    generator.init(256);
    //generates a secret key
    SecretKey secretkey = generator.generateKey();
    // returns an AES cipher
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    //print key
    System.out.println("Key: " + cipher);








    String plainText = "Hello World";
    // call to method encrypt 
    String hexEncryptedByteText  = encrypt(plainText, secretkey);
    // print orignial text and encrypted text
    System.out.println("Plain Text: " + plainText);
    System.out.println("Encrypted Text: " + hexEncryptedByteText);

    int plainTextlength = plainText.length();
    System.out.println("length of text: " + plainTextlength);


    // allows to write data to a file
    FileOutputStream fos = null;
    // write bytes to file
    BufferedOutputStream bos = null;
    // create file to which data needs to be written
    String fileName = "C:/Users/******/newFile.txt";

    try{
        // allows written data to go into the written path
        fos = new FileOutputStream(fileName);
        // converts written data into bytes
        bos = new BufferedOutputStream(fos);


        // writes the encrypted text into file
        bos.write(hexEncryptedByteText.length());                


        System.out.println("encryptedText has been written successfully in "
                     +fileName);

        // allows to catch bug in code
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try{
            // check for null exception
            if (bos != null){
                bos.close();

            }
            // check for null exception
            if (fos != null){
                fos.close();
            }
        } catch (IOException e){
            e.printStackTrace();

        }



    }






    // creates a file input stream by opening a path to the file needed
    FileInputStream fin = new FileInputStream("C:/Users/*****/public.cert");
    // implements the X509 certificate type
    CertificateFactory f = CertificateFactory.getInstance("X.509");
    // initalizes data found in the file
    X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
    // gets public key from this certificate 
    PublicKey pk = certificate.getPublicKey();
    System.out.println(pk);

    String hexEncryptedByteKey = encryptedKey(pk, secretkey);
    System.out.println("Encrypted Key: " + hexEncryptedByteKey);
    System.out.println("Encrypted Key length: " + hexEncryptedByteKey.length());

    // allows to write data to a file
    FileOutputStream newFos = null;
    // write bytes to file
    BufferedOutputStream newBos = null;
    // create file to which data needs to be written
    String fileNameKey = "C:/Users/****/symmetric.txt";

    try{
        // allows written data to go into the written path
        newFos = new FileOutputStream(fileNameKey);
        // converts written data into bytes
        newBos = new BufferedOutputStream(newFos);



        // writes the encrypted text into file
        newBos.write(hexEncryptedByteKey.length());                


        System.out.println("encryptedKey has been written successfully in "
                     +fileNameKey);






        // allows to catch bug in code
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try{
            // check for null exception
            if (newBos != null){
                newBos.close();

            }
            // check for null exception
            if (newFos != null){
                newFos.close();
            }
        } catch (IOException e){
            e.printStackTrace();

        }
    }

    // load keystore to get private key
    KeyStore ks = KeyStore.getInstance("JKS");
    String password = "*****";
    char[] passwordChar = password.toCharArray();
    System.out.println("password: " + passwordChar);
    // locate file
    try (FileInputStream fis = new FileInputStream("C:/Users/*****/keystore.jks")) {
        ks.load(fis, passwordChar);
    }

    // protect password for keystore
    KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(passwordChar);

    // get private key from keystore 
    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
            ks.getEntry("*****", protParam);

    PrivateKey myPrivateKey = pkEntry.getPrivateKey();

    System.out.println("private key: " + myPrivateKey);
    //method declaration
    String decryptedKey = decryptedKey(myPrivateKey, hexEncryptedByteKey);

    System.out.println("decrypted Key: " + decryptedKey);

    String hexDecryptedByteText = decryptedTextHex(decryptedKey, hexEncryptedByteText);
    System.out.println("key: " + hexDecryptedByteText);

}




public static String encrypt(String plainText, SecretKey secretkey) throws Exception {
    //Encodes the string into a sequence of bytes
    byte[] plainTextByte = plainText.getBytes();
    //intialize cipher to encryption mode
    cipher.init(Cipher.ENCRYPT_MODE, secretkey);
    //data is encrypted 
    byte[] encryptedByte = cipher.doFinal(plainTextByte);
    //Base64.Encoder encoder = Base64.getEncoder();
    //encodes bytes into a string using Base64
    byte[] encryptedByteText = Base64.getEncoder().encode(plainTextByte);
    String hexEncryptedByteText = DatatypeConverter.printHexBinary(plainTextByte);
    // return the string encrypted text to the main method
    return hexEncryptedByteText;

}

public static String encryptedKey(PublicKey pk, SecretKey secretkey) throws Exception {
    // data written to byte array
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // writes data types to the output stream
    ObjectOutputStream writter = new ObjectOutputStream(baos);
    //specific object of secretkey is written to the output stream
    writter.writeObject(secretkey);

    //creates a byte array  
    byte[] plainTextByteKey = baos.toByteArray();

    //creates a cipher using the RSA algorithm 
    Cipher cipher = Cipher.getInstance("RSA");
    // initalizes cipher for encryption using the public key 
    cipher.init(Cipher.ENCRYPT_MODE, pk);
    //encrypts data
    //byte[] encryptedByteKey = Base64.getEncoder().encode(plainTextByteKey);

    String hexEncryptedByteKey = DatatypeConverter.printHexBinary(plainTextByteKey);
    //Base64.Encoder encoderKey = Base64.getEncoder();
    // encodes the byte array into a string.
    //String encryptedTextKey = new String(encryptedByteKey);
    return hexEncryptedByteKey;

}

private static String decryptedKey(PrivateKey myPrivateKey, String hexEncryptedByteKey) throws Exception {

    //ByteArrayOutputStream baosDecrypt = new ByteArrayOutputStream();
    //ObjectOutputStream writterDecrypt = new ObjectOutputStream(baosDecrypt);
    //writterDecrypt.writeObject(hexEncryptedByteKey);
    //byte[] byteKeyDecrypt = baosDecrypt.toByteArray();


    Cipher cipher;
    cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, myPrivateKey);
    //cipher.doFinal();

    //byte [] decryptedKey = Base64.getDecoder().decode(byteKeyDecrypt);
    //String decryptedTextKey = new String(byteKeyDecrypt);

    byte[] decodedHex = DatatypeConverter.parseHexBinary(hexEncryptedByteKey);
    System.out.println("decoded hex key: " + decodedHex);
    String decryptedKey = new String(decodedHex, "UTF-8");
    return decryptedKey;





}

private static String decryptedTextHex(String decryptedKey, String hexEncryptedByteText) throws Exception {

    byte[] decryptedTextByte = decryptedKey.getBytes();
    byte[] textString = hexEncryptedByteText.getBytes();
    SecretKey key = new SecretKeySpec(decryptedTextByte, 0, decryptedTextByte.length, "AES");


    Cipher cipher;
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    //IvParameterSpec iv = new IvParameterSpec(cipher.getIV());
    cipher.init(Cipher.DECRYPT_MODE, key);
    byte[] decodedTextHex = cipher.doFinal(textString);

    byte[] decoded = Base64.getDecoder().decode(decodedTextHex);

    String hexDecryptedByteText = DatatypeConverter.printHexBinary(decoded);


    return hexDecryptedByteText;



}

}

This is the error I am getting:

Exception in thread "main" java.security.InvalidKeyException: Parameters missing
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:469)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:313)
at javax.crypto.Cipher.implInit(Cipher.java:802)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1249)
at javax.crypto.Cipher.init(Cipher.java:1186)
at ReadFileExample.generatekey.decryptedTextHex(generatekey.java:289)
at ReadFileExample.generatekey.main(generatekey.java:202)

I am not sure what is wrong. If my decryption of key is wrong or just the decryption of the String. I get no errors when it comes to the decryption of the key however.

For some more information: I generated a secret key, encrypted a String with the secret key and then encrypted the secret key with a generated public key. Then I decrypted the secret key with the private key and lastly I need to decrypt the String with the decrypted secret key.

Help is greatly appreciated. I have been working on this for so long and I just don't know what to do anymore. ]

EDIT: That other question has nothing to do with my question. I don't even have that same error message and I have already downloaded the JCE as that solution has stated.

Upvotes: 1

Views: 2024

Answers (1)

Farooq Khan
Farooq Khan

Reputation: 580

You have to be carefull with the key size, AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits so if your key size is any different you will get exceptions, also if you keysize is greater than 128 then the code wont work unless you have Unlimited policy files. Basically there is quite a bit detail to this. If you want to see some working code check out this link: https://github.com/Jsondb/jsondb-core/blob/master/src/main/java/io/jsondb/crypto/DefaultAESCBCCipher.java

Upvotes: 0

Related Questions