my task is to encrypt a file that is uploaded to S3. The upload worked fine before the encryption but now after I encrypted the file I get this exception.
The XML you provided was not well-formed or did not validate against our published schema
I added this to the existing Code
final AwsCrypto crypto = new AwsCrypto();
try (
final FileInputStream in = new FileInputStream(encryptfile);
final FileOutputStream out = new FileOutputStream(file);
final CryptoOutputStream<?> encryptingStream = crypto.createEncryptingStream(crypt, out))
{
IOUtils.copy(in, encryptingStream);
}
My thoughts, Why does AmazonS3 expect a XML-File ? Why not a normal text document ?
Is there a Option to change this maybe with the Bucket Policy ?
EDIT
That is the upload code, maybe there is a Issue. I dont understand why it´s working without the encryption.
File uploaffile = encryptFile(file);
List<PartETag> partETags = new ArrayList<PartETag>();
String filename = String.valueOf(System.currentTimeMillis());
InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(awss3bucket, filename);
InitiateMultipartUploadResult initResponse = amazons3.initiateMultipartUpload(initRequest);
long partSize = 5 * 1024 * 1024;
long contentLength = uploaffile.length();
long filePosition = 0;
for (int i = 1; filePosition < contentLength; i++) {
partSize = Math.min(partSize, (contentLength - filePosition));
UploadPartRequest uploadRequest = new UploadPartRequest()
.withBucketName(awss3bucket)
.withKey(filename)
.withUploadId(initResponse.getUploadId())
.withPartNumber(i)
.withFileOffset(filePosition)
.withFile(uploaffile)
.withPartSize(partSize);
PartETag petag = new PartETag(amazons3.uploadPart(uploadRequest).getPartNumber(), amazons3.uploadPart(uploadRequest).getETag());
partETags.add(petag);
filePosition += partSize;
}
CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(awss3bucket, filename,
initResponse.getUploadId(), partETags);
amazons3.completeMultipartUpload(compRequest);
Maybe next time I should stop to copy some random Code from the Internet.
You use The FileoutputStream to write not the other way. So the File so was Empty which created the Exception.
CryptoInputStream<KmsMasterKey> encryptingStream = crypto.createEncryptingStream(crypt, in);
FileOutputStream out = null;
try {
out = new FileOutputStream(encryptfile);
IOUtils.copy(encryptingStream, out);
encryptingStream.close();
out.close();
} catch (IOException e)
Related
I have a pdf Document and that need to be digitally signed and the signature is provided by external service. I don't have the certificate chain prior to initiate the signature. I tried the following code but getting SigDict/Contents illegal data message.
source to create document hash and post that to external service to sign it
InputStream data = null;
DocumentSignStatus documentSignStatus = new DocumentSignStatus();
int contentEstimated = 8192;
PdfReader reader = new PdfReader(requestParams.getDocumentToBeSigned());
try {
reader.unethicalreading = true;
int pdfPagenumber = 1;
if((Integer)requestParams.getSignPageNo() == null || requestParams.getSignPageNo()==0 ){
//pdfPagenumber = 1; // Default signature on first page.
pdfPagenumber = reader.getNumberOfPages(); // Sign on last page
}else {
pdfPagenumber = requestParams.getSignPageNo();
}
PdfSignatureAppearance appearance = null;
ByteArrayOutputStream os = null;
os = new ByteArrayOutputStream ();
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
Calendar cal = Calendar.getInstance();
appearance = stamper.getSignatureAppearance();
appearance.setSignDate(cal);
appearance.setAcro6Layers(false);
appearance.setReason("Test Signature");
appearance.setLocation("India");
appearance.setImage(null);
appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
Rectangle rect = requestParams.getRect();
appearance.setVisibleSignature(rect, pdfPagenumber, null);
HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2));
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
dic.setReason(appearance.getReason());
dic.setLocation(appearance.getLocation());
dic.setContact(appearance.getContact());
dic.setDate(new PdfDate(appearance.getSignDate()));
appearance.setCryptoDictionary(dic);
appearance.preClose(exc);
data = appearance.getRangeStream();
MessageDigest messageDigest;
String provider = null;
String hashAlgorithm = DigestAlgorithms.SHA256;
if (provider == null){
messageDigest = MessageDigest.getInstance(hashAlgorithm);
}else {
messageDigest = MessageDigest.getInstance(hashAlgorithm,provider);
}
int read = 0;
byte[] buff = new byte[contentEstimated];
while ((read = data.read(buff, 0, contentEstimated)) > 0)
{
messageDigest.update(buff,0,read);
}
byte[] hashDigest = messageDigest.digest();
byte[] documentHash = org.bouncycastle.util.encoders.Hex.encode(hashDigest);
//eSign Start
String hashdocument = new String(documentHash, "UTF-8");
System.out.println("Document Hash :"+hashdocument);
//Generate Sign Request XML for external source to sign the document hash
String eSignXmlStr = esignXML.generateEsignXML20(hashdocument,requestParams.getAadhaarNo());
String eSignSignedXML = myXMLSigner.signXML(eSignXmlStr, true);
System.out.print("sign request xml: " + eSignSignedXML);
// sign request xml generation complete
documentSignStatus.setSignedXML(eSignSignedXML);
session.put("hashdocument", documentHash);
session.put("appearance", appearance);
session.put("baos", os);
}catch(Exception e) {
e.printStackTrace();
}
return documentSignStatus;
Following is the source to attach the PKCS7 response to pdf to complete the signature procedure and get the signed pdf.
byte[] hashdocument = (byte[])session.get("hashdocument");
PdfSignatureAppearance appearance = (PdfSignatureAppearance)session.get("appearance");
ByteArrayOutputStream os = (ByteArrayOutputStream)session.get("baos");
//Get signed response xml
InputStream x = request.getInputStream();
String responseXML = IOUtils.toString(x, "UTF-8");
System.out.print("REsponse:" + responseXML);
//parse the xml and get pkcs7 data
String pkcs7asString = getPKCS7DataFromDigitalSignatureResponse(responseXML);
byte[] signedDocByte = org.bouncycastle.util.encoders.Base64.decode(pkcs7asString);
//////////////////// ADD SIGNED BYTES/HASH TO PDF DOCUMENT.
int contentEstimated = 8129;
byte[] paddedSig = new byte[contentEstimated];
System.arraycopy(signedDocByte, 0, paddedSig, 0, signedDocByte.length);
PdfDictionary dic2 = new PdfDictionary();
dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
try {
appearance.close(dic2);
} catch (DocumentException e) {
e.printStackTrace();
}
try(OutputStream outputStream = new FileOutputStream("/SignTest2.0.pdf")) {
os.writeTo(outputStream);
}
os.close();
The method getPKCS7DataFromDigitalSignatureResponse(responseXML) is used to parse the external service response it returns a PKCS7 as String.
I tried to figure out the problem but couldn't find the root cause.
can anyone help to sort out this issue. Using itext version 5.4.5 copy od signed document is PDF with Signature Problem
I found the root cause of the issue, I made a small mistake, the content estimation variable in not correct in above source due to that paddedSig was not created properly.
Wrong value as shown in above source. int contentEstimated = 8129;
Correct Value is int contentEstimated = 8192;
Rest of the code is fine.
I programmed a little example of working with zip-files in java. Actually I'm wondering, if there is a faster way to extract such a file. If i'm testing my tool with bigger files(Like 1GB or more) the process takes really to long.
I'm thankful for every advice.
Im doing it like this:
private void extractFolder(String zipFile, String extractFolder)
{
try
{
int BUFFER = 2048;
File file = new File(zipFile);
ZipFile zip = new ZipFile(file);
String newPath = extractFolder;
new File(newPath).mkdir();
Enumeration zipFiles = zip.entries();
while (zipFiles.hasMoreElements())
{
ZipEntry entry = (ZipEntry) zipFiles.nextElement();
String currentEntry = entry.getName();
File destFile = new File(newPath, currentEntry);
// destFile = new File(newPath, destFile.getName());
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if (!entry.isDirectory())
{
BufferedInputStream inputSteam = new BufferedInputStream(zip.getInputStream(entry));
int currentByte;
// init buffer
byte data[] = new byte[BUFFER];
FileOutputStream outStream = new FileOutputStream(destFile);
BufferedOutputStream bufferedOutSteam = new BufferedOutputStream(outStream, BUFFER);
while ((currentByte = inputSteam.read(data, 0, BUFFER)) != -1)
{
bufferedOutSteam.write(data, 0, currentByte);
}
bufferedOutSteam.flush();
outStream.flush();
bufferedOutSteam.close();
inputSteam.close();
outStream.close();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
Maybe that is not precisely the answer you are waiting for but you want to try this package; with the latest stable version your code can be "reduced" to this (note that the destination directory must not exist):
final Path zipFile = Paths.get("path/to/file.zip");
final Path dstDir = Paths.get("path/to/destination/directory");
try (
final FileSystem zipfs = MoreFileSystems.openZip(zipFile, true);
) {
MoreFiles.copyRecursize(zipfs.getPath("/"), dstDir,
RecursionMode.FAIL_FAST);
}
This will use the JRE's provided zip filesystem provider; it may or may not be optimized for your use case (I haven't checked!).
Javadoc links:
MoreFileSystems.openZip();
MoreFiles.copyRecursive()
Steps I've followed:
1) Store the images in Blobstore.(This is necessary)
2) Fetch the images from blobstore and save it in GCS bucket.
If I store the image file directly to GCS bucket then it works fine.
But I want to fetch it from Blobstore.
Map<String, List<BlobInfo>> blobsData = blobstoreService.getBlobInfos(req);
for (String key : blobsData.keySet())
{
for(BlobInfo blob:blobsData.get(key))
{
byte[] b = new byte[(int)blob.getSize()];
BlobstoreInputStream in = new BlobstoreInputStream(blob.getBlobKey());
in.read(b);
GcsService gcsService = GcsServiceFactory.createGcsService();
GcsFilename filename = new GcsFilename("casfilestorage", blob.getFilename());
GSFileOptionsBuilder builder = new GSFileOptionsBuilder()
.setAcl("public_read")
.setBucket(BUCKET_NAME)
.setKey(blob.getFilename())
.setMimeType(blob.getContentType());
AppEngineFile writableFile = fileService.createNewGSFile(builder.build());
boolean lock = true;
writeChannel = fileService.openWriteChannel(writableFile, lock);
os = Channels.newOutputStream(writeChannel);
UploadOptions uploadOptions = UploadOptions.Builder.withGoogleStorageBucketName("casgaestorage");
//String uploadUrl = blobstoreService.createUploadUrl("/serve", uploadOptions);
os.close();
writeChannel.closeFinally();
in.close();
}
}
Refer below code, Just pass your byte[] to write method:
GcsService f_ObjGcsService = GcsServiceFactory.createGcsService();
GcsFilename f_ObjFilename = new GcsFilename("BUCKET NAME", "FileName");
GcsFileOptions f_ObjOptions = new GcsFileOptions.Builder()
.mimeType("Content Type")
.acl("public-read")
.build();
GcsOutputChannel f_ObjWriteChannel = f_ObjGcsService.createOrReplace("Filename", f_ObjOptions);
PrintWriter f_ObjWriter = new PrintWriter(Channels.newWriter(f_ObjWriteChannel, "UTF8"));
f_ObjWriter.flush();
f_ObjWriteChannel.waitForOutstandingWrites();
f_ObjWriteChannel.write(ByteBuffer.wrap("Byte Array that u get from blob"));
f_ObjWriteChannel.close();
I am getting zipped blob from db and using that blob in below way,
Ex:-
byte[] inputBlob = blobfile.getBytes(1, (int) blobfile.length());
After getting the blob, the way i got the zippedStream and passed it into another Class method(unzipper).
Ex:-
ByteArrayOutputStream zippedStream = null;
InputStream byteInputStream = null;
IParser parser = null;
byte[] buffer = null;
try {
zippedStream = new ByteArrayOutputStream();
byteInputStream = new ByteArrayInputStream(blob);
blob = null;
int bytes_read;
buffer = new byte[byteInputStream.available()];
while ((bytes_read = byteInputStream.read(buffer)) > 0) {
zippedStream.write(buffer, 0, bytes_read);
}
buffer = null;
byteInputStream.close();
byteInputStream = null;
}catch(Exception e){
e.printStackTrace();
}
unzipper method:
Ex:-
byte[] buffer = new byte[1024];
try {
InputStream decodedInput = new ByteArrayInputStream(zippedStream.toByteArray());
zippedStream.close();
zippedStream = null;
GZIPInputStream unzippedStream = new GZIPInputStream(decodedInput);
decodedInput.close();
decodedInput = null;
int bytes_read;
unzippedOutputstream = new ByteArrayOutputStream();
while ((bytes_read = unzippedStream.read(buffer)) > 0) {
unzippedOutputstream.write(buffer, 0, bytes_read);
}
buffer = null;
unzippedStream.close();
unzippedStream = null;
} catch (Exception ex) {
logger.setException(ex);
logger.error("unzipper", generateMsg("Exception occurred"));
}
Using this way my application got stucked some time, and performance was so bad.
Is there any optimize way to get the zippedstream file and unzipping that easily?
Is all this buffering really needed. Can you IParser parse a Stream?
InputStream zippedStream = ...
IParser parser = ...
parser.parse(new GZIPInputStream(zippedStream));
This will read compressed data, uncompressing as it goes which is much more efficient.
I wrote some code that lets me save pictures in my data/data in Android internal storage. Now I would like to know if there is a way to delete those pictures from internal storage.
Here is what I have for saving:
public boolean saveImg( String showId ) {
try {
URL url = new URL(getImgUrl( showId ));
File file = new File(showId + ".jpg");
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
//Define InputStreams to read from the URLConnection.
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
//Read bytes to the Buffer until there is nothing more to read(-1).
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
//Convert the Bytes read to a String.
FileOutputStream fos = new FileOutputStream(PATH+file);
fos.write(baf.toByteArray());
fos.close();
return true;
} catch (IOException e) {
return false;
}
}
I tried this but it doesn't delete from data/data. Any suggestions as to what I'm doing wrong?
public void DeleteImg(String showId) {
File file = new File( PATH + showId +".jpg" );
file.delete();
}
Try this:
File file = new File(selectedFilePath);
boolean deleted = file.delete();