java Aes encryption using key file - java

How can we store the KEY in a key file for AES encryption using java so that the key file can be used for decryption purpose.
private static void storeKey(SecretKey key){
byte[] keyb = key.getEncoded();
FileOutputStream keyfos;
try {
File file = new File(generateKeyFilesPath);
if (!file.exists()) {
file.createNewFile();
}
keyfos = new FileOutputStream(file);
keyfos.write(keyb);
keyfos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static SecretKeySpec getKey(String generateKeyFilesPath){
SecretKeySpec key = null;
try {
File keyFile = new File(path);
FileInputStream stream = new FileInputStream(keyFile);
byte[] bytesArray = new byte[(int) keyFile.length()];
stream.read(bytesArray);
stream.close();
key = new SecretKeySpec(bytesArray, "AES");
} catch (Exception e) {
e.printStackTrace();
}
return key;
}
Unable to decrypt the cipher using the stored key(file),

Related

How to decrypt ByteArrayOutputStream in Java.?

I am trying to decrypt a file downloaded as ByteArrayOutputStream from Azure Storage.
I have a stream of type ByteArrayOutputStream.
How can I decrypt it and return decrypted ByteArrayOutputStream.?
I have tried using CipherOutputStream, but I'm not sure how to use it.
Below is the code (snippet) I am using to encrypt the file before uploading
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
blob.upload(new CipherInputStream(file.getInputStream(), cipher), file.getSize());
Below is my code:
public ByteArrayOutputStream download(String fileName, Long id) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encrypkey.getBytes("UTF-8"), "AES");
cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8")));
CipherOutputStream output = null;
container = getBlobClient().getContainerReference("container" + id.toString());
CloudBlockBlob blob = container.getBlockBlobReference(fileName);
if (blob.exists()) {
blob.download(os);
//output = new CipherOutputStream(outputStream, cipher);
} else {
logger.info("File does not exists on azure container");
}
} catch (StorageException e) {
logger.error("StorageException : {}" + e.getLocalizedMessage(), e);
} catch (Exception e) {
logger.error("Exception : {}" + e.getLocalizedMessage(), e);
}
return os;
}
First create the CipherOutputStream, then download the blob into that output:
output = new CipherOutputStream(os, cipher);
blob.download(output);

How to fix No such file or directory in Android

In my application i have Decrypt file with AES256 and CBC .
i have written below codes, to check if file exists.
But when run application it shows me an error and not can open my file!
I used Log.e to show files's path and it shows me this path. but it says can not open file!
My code :
private SecureRandom r;
private byte[] _iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
r = new SecureRandom();
_iv = new byte[16];
r.nextBytes(_iv);
String inputFile = getRootDirPath(context) + "/"+bookName;
String outPutFile = getRootDirPath(context) + "/BookFile_716798_decrypt3.html";
File file = new File(inputFile);
if (file.exists()) {
try {
decrypt(inputFile, encryptionPassword, outPutFile, "");
Log.e("DecryptLog", "0");
} catch (IOException e) {
e.printStackTrace();
Log.e("DecryptLog", "1 : " + e.getMessage());
Log.e("DecryptLog", "\nPath : " + inputFile);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
Log.e("DecryptLog", "2 : " + e.getMessage());
} catch (NoSuchPaddingException e) {
e.printStackTrace();
Log.e("DecryptLog", "3 : " + e.getMessage());
} catch (InvalidKeyException e) {
e.printStackTrace();
Log.e("DecryptLog", "4 : " + e.getMessage());
}
} else {
Toast.makeText(context, "Not", Toast.LENGTH_SHORT).show();
}
}
public String getRootDirPath(Context context) {
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
File file = ContextCompat.getExternalFilesDirs(context.getApplicationContext(),
null)[0];
return file.getAbsolutePath();
} else {
return context.getApplicationContext().getFilesDir().getAbsolutePath();
}
}
private void decrypt(String path, String password, String _initVector, String outPath)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream(path);
FileOutputStream fos = new FileOutputStream(outPath);
byte[] key = (password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
try {
cipher.init(Cipher.DECRYPT_MODE, sks, new IvParameterSpec(_iv));
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
After run application show me this error :
2020-08-01 08:03:59.324 28560-28560/com.app.appE/DecryptLog: 1 : : open failed: ENOENT (No such file or directory)
2020-08-01 08:03:59.324 28560-28560/com.app.app E/DecryptLog: Path : /storage/emulated/0/Android/data/com.app.app/files/BookFile_716798.html

How to use Decrypt file with AES in Android

In my application I want to download an HTML file from server, then decrypt this file and show into webView!
The backend developer uses this library for encrypt file from server: https://github.com/soarecostin/file-vault
I wrote the code below, but when decrypting a file, it shows an error in Logcat and doesn't decrypt this file!
My code:
encryptionPassword = "7BOF%aZQMpfJ#2wUS*S6!#K+ZB$Sz+J0";
String inputFile = FileUtils.getDirPath(this) + "/BookFile_716798.html";
String outPutFile = FileUtils.getDirPath(this) + "/BookFile_716798_decrypt.html";
try {
decrypt(inputFile, encryptionPassword, outPutFile);
Log.e("DecryptLog", "0");
} catch (IOException e) {
e.printStackTrace();
Log.e("DecryptLog", "1");
Log.e("DecryptLog", "" + e.getMessage());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
Log.e("DecryptLog", "2");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
Log.e("DecryptLog", "3");
} catch (InvalidKeyException e) {
e.printStackTrace();
Log.e("DecryptLog", "4");
}
private void decrypt(String path, String password, String outPath)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream(path);
FileOutputStream fos = new FileOutputStream(outPath);
byte[] key = (password).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while ((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
This message is shown in logCat:
2020-07-31 21:52:39.881 1367-1367/com.app.app E/DecryptLog: 1
2020-07-31 21:52:39.881 1367-1367/com.app.appE/DecryptLog: javax.crypto.BadPaddingException: pad block corrupted
How can I fix it?

how to unzip file which zipped and encrypted with CipherInputStream and ZipInputStream

I have the following code and it's OK when creating an encrypted zip file with the given file, however, I could not open the generated zip file with unzip command and it complains invalid zip.
"The Unarchiver" could not unzip as well.
public void encrypt(String desKey, String zipFileName, String fileName) {
InputStream inputStream = null;
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(zipFileName);
SecretKey keySpec = new SecretKeySpec(desKey.getBytes(), "DESede");
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
InputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
ZipInputStream zipInputStream = new ZipInputStream(cipherInputStream);
ZipEntry nextEntry = zipInputStream.getNextEntry();
inputStream = zipInputStream;
if (nextEntry == null) {
System.out.println("error");
inputStream = null;
}
fileOutputStream = new FileOutputStream(fileName);
IOUtils.copy(inputStream, fileOutputStream);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
} else if (fileInputStream != null) {
fileInputStream.close();
} else if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Zipping a stream does not means that you create a zip file... If you want to create a zip file with a crypted file in it, you should create ZipEntry, add it to the ZipOutputStream and then push your encrypted data. You can have a look at http://www.oracle.com/technetwork/articles/java/compress-1565076.html wich is a good starting point.

Decrypted string not the same as pre encrypted string

I have the following pieces of code:
Globals
public static PublicKey pubKey;
public static PrivateKey privKey;
public static Cipher cip;
Main
public static void main(String[] args) throws Exception {
//Generate the keys
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
KeyFactory fact = KeyFactory.getInstance("RSA");
cip = Cipher.getInstance("RSA/ECB/NoPadding");
// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream("public.key");
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream("private.key");
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
//Get the public and private keys out of their files
getPubAndPrivateKey();
//Check if the keys gotten out of the files are the same as the generated files (this returns truetrue)
System.out.print(publicKey.equals(pubKey));
System.out.print(privateKey.equals(privKey));
byte[] text = "This is my super secret secret".getBytes();
encryptToFile("encrypted.txt", text );
decryptToFile("encrypted.txt", "decrypted.txt");
}
Getting the keys from the files
private static void getPubAndPrivateKey() throws IOException, Exception {
// Read Public Key.
File filePublicKey = new File("public.key");
FileInputStream fis = new FileInputStream("public.key");
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File("private.key");
fis = new FileInputStream("private.key");
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
pubKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
privKey = keyFactory.generatePrivate(privateKeySpec);
}
Encrypting
public static void encryptToFile(String fileName, byte[] data)
throws IOException {
try {
cip.init(Cipher.ENCRYPT_MODE, privKey);
byte[] cipherData = cip.doFinal(data);
String encryptedData = cipherData.toString();
BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
out.write(encryptedData);
out.close();
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
}
}
Decrypting
private static void decryptToFile(String string, String string2)
throws Exception {
try {
File encryptedFile = new File("encrypted.txt");
byte[] encrypted = getContents(encryptedFile).getBytes();
cip = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cip.init(Cipher.DECRYPT_MODE, pubKey);
byte[] cipherData = cip.doFinal(encrypted);
String decryptedData = cipherData.toString();
BufferedWriter out = new BufferedWriter(new FileWriter(
"decrypted.txt"));
out.write(decryptedData);
out.close();
} catch (Exception e) {
throw e;
}
}
Things I already checked
The data used in the decryption is the same as in the encrypted file
The generated keys are the same as the ones gotten from the file
The encryption and decryption both don't give errors
Results
Original string:
My super secret secret
The encryption results in:
[B#1747b17
The decryption results in:
[B#91a4fb
If you print out a byte array via toString() method you are getting a value that is totally independent of the content.
Therefore the values [B#1747b17 [B#91a4fb are just garbage that does not tell you anything.
If you want to print the content of a byte array convert it to Base64 or hex-string.
System.out.println(new sun.misc.BASE64Encoder().encode(myByteArray));
A hex string can be generated by using org.apache.commons.codec.binary.Hex from Apache Commons Codec library.
I agree with the above answer.
I would like to add that in your case, you can simply use FileOutputStream, write the bytes to a file -
For example:
public static void encryptToFile(String fileName, byte[] data)
throws IOException {
FileOutputStream out = null;
try {
cip.init(Cipher.ENCRYPT_MODE, privKey);
byte[] cipherData = cip.doFinal(data);
out = new FileOutputStream(fileName);
out.write(cipherData);
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ex) {
}
}
}
}

Categories

Resources