I use the X509V2AttributeCertificate from Bouncycastle. The problem is, that it is deprecated but I do not find any replacement for the exisiting (deprecated) code. Does someone know the new way?
My way: I use a X509AttributeCertificateHolder, this holder contains the certificate. When I communicate with a client I don't want to send the holder instead I want to send the X509V2AttributeCertificate (for me it seems to be the cleaner code). To do this I use the following code (the client is the file):
X509V2AttributeCertificate certitificate = new X509V2AttributeCertificate(att.getEncoded());
// Store to file (send the byte[] to the client)
String fileName = "test";
FileOutputStream fos = new FileOutputStream(fileName);
fos.write(certitificate.getEncoded());
fos.close();
// Read from file (decode the received certificate)
byte[] readCertificate = Files.readAllBytes(new File(fileName).toPath());
X509V2AttributeCertificate decodedCertificate = new X509V2AttributeCertificate(readCertificate);
How should the X509V2AttributeCertificate be replaced?
Related
I have a zip file that is AES encrypted. After decrypting I'm left with a byte[] containing the zip content. But when I try to unzip it, using a ByteArrayInputStream, ZipInputStream.getNextEntry() returns null right away. Debugging, I see that my byte[] doesn't have a required local file header signature which is
static long LOCSIG = 0x04034b50L; // "PK\003\004"
so ZipInputStream.getNextEntry() returns null.
If, however, I write those decrypted bytes out to a file and then use a FileInputStream() that I pass to ZipInputStream(), everything works as expected. Below is my current code. Can anyone suggest a way to unzip without first writing out to a temporary file?
byte[] data = AESUtil.decryptInputStream(...);
ByteArrayInputStream bis = new ByteArrayInputStream(data);
ZipInputStream stream = new ZipInputStream(bis);
ZipEntry entry;
while ((entry = stream.getNextEntry()) != null) {
...
}
I've come to the conclusion that ZipInputStream just isn't flexible enough. When I substituted the above code with Apache Commons' compress classes, everything works. Below is a working implementation using that library and the same byte array:
byte[] data = AESUtil.decryptInputStream(...);
SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(data);
ZipFile zipFile = new ZipFile(inMemoryByteChannel);
Iterator<ZipArchiveEntry> iterator = = zipFile.getEntriesInPhysicalOrder().asIterator();
while (iterator.hasNext()) {
...
}
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
I have a client server program where I need to serialize the file object and send it to the client.
At server side:
FileInputStream input_file = new FileInputStream(file);
object_output_stream.writeObject(input_file);
At client side:
FileOutputStream ouput_file = new FileOutputStream(new File(filename));
output_file = object_input_stream.readObject();
I need to serialize the input_file object and send it to the client. The ObjectOutputStream and ObjectInputStream are Non-Serializable. What would be the best way for this?
You cannot serialize files - that would imply that the client could read from a file at the server, which would require a complicated protocol that is simply not present in the Java serialization mechanism.
Your best best is to read the data from the file into a byte array, and to then either send the byte array plainly to the client, or to serialize the byte array in the ObjectOutputStream (you would do that if you want to send other objects as well)
You can use apache-commons IOUtils.toByteArray(InputStream input) to read a file into a byte[] easily.
On the server side:
FileInputStream input_file = new FileInputStream(file);
byte[] input_data = IOUtils.toByteArray(input_file);
object_output_stream.writeObject(input_data);
On the client side:
FileOutputStream output_file = new FileOutputStream(new File(filename));
byte[] input_data = (byte[]) object_input_stream.readObject();
output_file.write(input_data);
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.
In my java application I want to transfer some Images from client to server.
I am using Socket to connect client with server.
It is working when I transfer string from client to server but I am not able to transfer Image file.
I am using
BufferedInputStream
BufferedOutputStream
for transferring string.
I know for transferring file I need to use FileInputStream as:
BufferedInputStream bis bis = new BufferedInputStream(new FileInputStream("111.JPG"));
But I don't know, what exactly I need to write.
so please give your answer by some sample of code.
You should convert image to byte.
You can use this function.
static byte[] ImageToByte(System.Drawing.Image iImage)
{
MemoryStream mMemoryStream = new MemoryStream();
iImage.Save(mMemoryStream,
System.Drawing.Imaging.ImageFormat.Gif);
return mMemoryStream.ToArray();
}
And you can call this function in your server program.
Bitmap tImage = new Bitmap(Image URL goes here);
byte[] bStream = ImageToByte(tImage);
while (true)
{
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected");
while (client.Connected)
{
NetworkStream nStream = client.GetStream();
nStream.Write(bStream, 0,
bStream.Length);
}
}
There are many examples on the internet already:
here
here
etc.
Please consider using google next time.