BouncyCastle openPGP encrypt byte[] array as csv file - java

I have gotten my code to be able to load in a public key, and encrypt a byte[] array with a public key someone else has provided. However, when i decrypt the file, it doesn't have a .csv extension. I can open it in Excel and it looks like a csv once I open it, but the file just doesn't have any extension associated to it, so I have to weirdly open it in Excel.
I've also attached my code below and I just couldn't figure out where to modify it so that when I decrypt it using Kleopatra, it shows with a .csv extension. I tried to change my output stream to a .csv from a .gpg file, but then it throws an error saying that it could not determine whether this is a OpenPGP signature. I think I have to do something with the lData.open() method, but the only options I can put there are PGPLiteralData.TEXT, BINARY, and UTF8. Maybe this has to do with adding a signature to the file?
Btw, for the code below, the public key is already loaded into a variable called pubkey.
byte[] bytesArray = getAccessChannels(customerAlias);
OutputStream out = new FileOutputStream("/path/to/file/eData.gpg");
Security.addProvider(new BouncyCastleProvider());
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);
OutputStream cos = comData.open(bOut); // open it with the final destination
PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
OutputStream pOut = lData.open(cos, PGPLiteralData.TEXT, "Report.csv", bytesArray.length, new Date());
pOut.write(bytesArray);
lData.close();
comData.close();
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setSecureRandom(new SecureRandom()));
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(pubKey));
byte[] bytes = bOut.toByteArray();
OutputStream cOut = cPk.open(out, bytes.length);
cOut.write(bytes); // obtain the actual bytes from the compressed stream
cOut.close();

Nevermind, I just needed to change the file extension to eData.csv.gpg...this took me a whole 2 days

Related

Java in websphere produces corrupted zip file, if previously zipped content as byte array is written into file

my java zip problem apeears only in websphere in linux environment,
but works on my local windows developer computer in tomee all right.
I try to compress a content and send the result as mail and backup the same content in a folder.
My input data is a CSV file content in a byte-array.
I compress the input byte array to a zip result byte array.
I try to save my zipped result data in a folder and send the same content as a mail attachment.
Result: zip-attachment in mail is delivered correctly but the same zip byte array saved as a file is corrupted.
public static byte[] zipContent(String filename, byte[] content) throws IOException {
final CRC32 crc = new CRC32();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (final ZipOutputStream zipOut = new ZipOutputStream(baos);
final InputStream fis = new ByteArrayInputStream(content);) {
crc.reset();
final ZipEntry zipEntry = new ZipEntry(filename);
zipOut.putNextEntry(zipEntry);
int length;
byte[] bytes = new byte[1024];
while ((length = fis.read(bytes)) >= 0) {
crc.update(bytes,0,length);
zipOut.write(bytes, 0, length);
}
final long crcValue = crc.getValue();
zipEntry.setCrc(crcValue);
zipEntry.setSize(content.length);
zipEntry.setComment("CRC_" + Long.toString(crcValue));
zipOut.closeEntry();
zipOut.flush();
} finally {
baos.flush();
baos.close();
}
return baos.toByteArray();
}
I call
final byte[] csvContentArray = ... // Get CSV input anyway ...
File csvFile = new File(aCsvPathString);
Files.write(csvfile.toPath(), csvContentArray); // OKAY, saved correctly pre compress in server
//COMPRESS: byte[] --> byte[]
final byte[] zippedContent = zipContent(csvFileName, csvContentArray);
File zipFile = new File(aZipPathString);
Files.write(zipfile.toPath(), zippedContent); // CORRUPTED, saved after compress in server !!!
...
sendMail(emailAdress, zippedContent); // the same zipped content in mail is delivered correctly and can be opened without warnings !
What differs for zip file content as byte[] between saving in file system and sending as mail attachment (MimeBodyPart).
It is very strange for me, because it works fine in Windows/Tomee but not in Linux/Websphere.
My zipped csv file is huge and after compressing, first about 1000 lines are fine. Rest of file is confused.
I tried to code with and without CRC by ZipEntry, but it doesn't matter.
Opening corrupted zip in 7zip gives warnings like:
Unerwartetes Datenende. Translated: unexpected data end.
Es gibt noch Daten hinter den Hauptdaten. Translated: existing data after main data.
I'm always grateful for opinions and suggestions.

java apache IOUtils breaks file content

I need to encode/decode pdf file into Base64 format.
So I read file from disk into String(because I will receive file in String Base64 format in future);
String pdfString = IOUtils.toString(new FileInputStream(new
File("D:\\vrpStamped.pdf")));
byte[] encoded = Base64.encodeBase64(pdfString.getBytes());
byte[] newPdfArray = Base64.decodeBase64(encoded);
FileOutputStream imageOutFile = new FileOutputStream(
"D:\\1.pdf");
imageOutFile.write(newPdfArray);
imageOutFile.close();
imageOutFile.flush();
So my D:\\1.pdf doesnt opens in AdobeReader, but if I read file straight to byte array, using IOUtils.toByteArray(..) instead ,all works fine and my D:\\1.pdf file sucessfuly opens in Adobe Reader:
byte[] encoded = Base64.encodeBase64(IOUtils.toByteArray(new FileInputStream(new File("D:\\vrpStamped.pdf"))););
It seems to me thath IOUtils.toString(..) change something inside file content. So how can I convert file to String with not content breaking?
How to encode a pdf...
byte[] bytes = IOUtils.toByteArray(new FileInputStream(new File("/home/fschaetz/test.pdf")));
byte[] encoded = Base64.encode(bytes);
String str = new String(encoded);
...now do something with this encoded String, for example, send it via a Rest service.
And now, if you receive an encoded String, you can decode and save it like this...
byte[] decoded = Base64.decode(str.getBytes());
FileOutputStream output = new FileOutputStream(new File("/home/fschaetz/result.pdf"));
output.write(decoded);
output.close();
Works perfectly fine with all files, not limited to images or pdfs.
What your example is doing is...
Read the pdf into a String (which pretty much destroys the data, since you are reading binary data into a String)
Encode this spring (which is in all likelyhood not a valid representation of the original pdf anymore)
Decode it and save it to disk

File exists but when I perform operation on that file, system shows FileNotFoundException. Works when file is in dir where source code is

public void decrypt() throws Exception
{
//opening streams
//Error is in the line below When i try to read file from directory
//other than the one which has .java and .class files.
FileInputStream fis1 =new FileInputStream(file);
File dir=new File("C:/Crypt-R/Decrypted");
dir.mkdirs();
file=new File(dir,file.getName() +".dec");
FileOutputStream fos1 =new FileOutputStream(file);
//generating same key
byte k[] = keyRecv.getBytes();
SecretKeySpec key = new SecretKeySpec(k,"AES");
//creating and initialising cipher and cipher streams
Cipher decrypt = Cipher.getInstance(algorithm);
decrypt.init(Cipher.DECRYPT_MODE, key);
CipherInputStream cin=new CipherInputStream(fis1, decrypt);
byte[] buf = new byte[1024];
int read=0;
while((read=cin.read(buf))!=-1) //reading encrypted data from file
{
fos1.write(buf,0,read); //writing decrypted data to file
}
//closing streams
cin.close();
fos1.flush();
fos1.close();
JOptionPane.showMessageDialog (null,
"File Decrypted",
"Success..!!",
JOptionPane.INFORMATION_MESSAGE);
}
There is a Text Editor attached to this program, file gets displayed in that Editor but when i am trying to decrypt it and it does not exist in the directory where my source code is kept then it shows file not found exception. Can you please help me out with this?
You need to check the following things
1) Make sure you are mentioning filename that really exists in the location
Check Reasons for getting FileNotFoundException
2) Then you have to mention path like "C:\\Users\...". Make sure you use right way to mention file names on windows system
3) You have to again check similarly for FileOutputStream.
You need to separate your directories with
File.separator
Which will hold the value of /, : or \\ depending on which platform you are on.

How to convert ByteBuffer to FileInputStream in Java?

I am trying to import xls sheet to DB, for that when i am uploading the file the uploaded file is in ByteBuffer Format, i have written a logic which reads as FileInputStream.
Now how do i convert this ByteBuffer to FileInputStream
Here is my Code
ByteBuffer fileBytes = (ByteBuffer) context.get("uploadedFile");
String encoding = System.getProperty("file.encoding");
String filename = Charset.forName(encoding).decode(fileBytes).toString();
filename = filename.replaceAll("\\r", "");
I tried Casting it using ByteArrayInputStream() but looks like it is not working!
Change your logic to use InputStream rather than FileInputStream. You don't care where the input comes from.
Use the following code:
ByteArrayInputStream bais = new ByteArrayInputStream(buffer.array(), buffer.position(), buffer.limit());
and pass bais to your existing method.

When and why decorate OutputStream with ArmoredOutputStream when using BouncyCastle

I'm pretty new to BouncyCastle and pgp. I've seen many articles and samples on the internet. Almost every encryption sample contains the code snipped below
if (armor)
out = new ArmoredOutputStream(out);
It seems that my local test passed with both armor and none-armor. I googled around but found few useful and the javadoc of ArmoredOutputStream only shows This is basic output stream.
So what's the difference and when to use it?
Complete code sample:
public static void encryptFile(String decryptedFilePath,
String encryptedFilePath,
String encKeyPath,
boolean armor,
boolean withIntegrityCheck)
throws Exception{
OutputStream out = new FileOutputStream(encryptedFilePath);
FileInputStream pubKey = new FileInputStream(encKeyPath);
PGPPublicKey encKey = readPublicKeyFromCollection2(pubKey);
Security.addProvider(new BouncyCastleProvider());
if (armor)
out = new ArmoredOutputStream(out);
// Init encrypted data generator
PGPEncryptedDataGenerator encryptedDataGenerator =
new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(),"BC");
encryptedDataGenerator.addMethod(encKey);
OutputStream encryptedOut = encryptedDataGenerator.open(out, new byte[BUFFER_SIZE]);
// Init compression
PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
OutputStream compressedOut = compressedDataGenerator.open(encryptedOut);
PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, decryptedFilePath, new Date(), new byte[BUFFER_SIZE]);
FileInputStream inputFileStream = new FileInputStream(decryptedFilePath);
byte[] buf = new byte[BUFFER_SIZE];
int len;
while((len = inputFileStream.read(buf))>0){
literalOut.write(buf,0,len);
}
literalOut.close();
literalDataGenerator.close();
compressedOut.close();
compressedDataGenerator.close();
encryptedOut.close();
encryptedDataGenerator.close();
inputFileStream.close();
out.close();
}
}
ArmoredOutputStream uses an encoding similar to Base64, so that binary non-printable bytes are converted to something text friendly. You'd do this if you wanted to send the data over email, or post on a site, or some other text medium.
It doesn't make a difference in terms of security. There is a slight expansion of the message size though. The choice really just depends on what you want to do with the output.
ASCII armor is a generic term that means a binary data representation as an ASCII-only text. Technically, there is a lot of ways to ascii-armor binary data, but in the cryptography-related field the PEM format is prevalent (also check this and related questions at serverfault).
The PEM is basically a Base64-encoded binary data wrapped in -----BEGIN SOMETHING----- and -----END SOMETHING----- delimiters and a set of additional headers that can contain some meta information about the binary content.

Categories

Resources