problems downloading signed pdf files c# - pdf

I have a signed pdf with Adobe signature well done. My problem starts when I want to download this document.
Via webmethod I get the bytes of the signed file. Until here there is no problems.
If I try to save the file in my server, when I open the file everything is correct. But if I try to download it when I open it the signature is wrong.
This is the error in adobe reader:
"The scope of the signed data is defined by a range of unexpected bytes.
Details: The range of bytes of the signature is invalid"
This is the way I download the file:
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename= Factura.pdf");
HttpContext.Current.Response.AddHeader("Content-Length", newStream.Length.ToString());
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.BufferOutput = true;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.OutputStream.Write(newStream.GetBuffer(), 0, newStream.GetBuffer().Length);
HttpContext.Current.Response.OutputStream.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();
Can anyone help me with this problem?

You are sending more bytes than thos advertised in the header. Do newStream.ToArray() and only use the byte array. Other thing to check is if you really have all the bytes in newStream, save it to a file to check (from the ToArray().

Related

GzipStream Compression

I am writing code for Request and Response web compression in vb.net using GzipStream. I need to take analysis before and after compression of Response. I have written below code to capture the Response data length after de-compression.
Using testStream As New GZipStream(response.GetResponseStream(), CompressionMode.Decompress)
Dim decompressedBytes(800000) As Byte
compLength = zippedStream.Read(decompressedBytes, 0, 800000)
WriteFileStream(compLength, Path, Length, methodURL)
Return testStream
End Using
"Stream was not readable" error is coming after Return testStream. Without zippedStream.Read code everything is working fine. "WriteFileStream" is just a method which writes the data into a file.
Any suggessions here.
Regards
sangeetha

If it isn't Base64, what might it be?

Original Question
I'm using an API to get a thumbnail image that I uploaded. Instead of providing me with a url to the image, the service returns me a garbles text string that I thought was Base64. However, all of my attempts to decode this string have failed. Does anyone have any ideas of what object types the service might be returning me? If it's not base64, what would it be?
screenshot on imgur of the API response
Answer to Original Question
#Andrew Tran: pointed out that the response I was getting looked like it was the raw binary data for the png file. This helped correct my lack of experience with Base64 and led me to some further research.
First Attempt at downloading the file
Dim path As String = "C:\Users\username\lpImages\img1.png"
Dim fs As FileStream = File.Create(path)
Dim info As Byte() = New UTF8Encoding(True).GetBytes(thumbnail)
fs.Write(info, 0, info.Length)
fs.Close()
This never worked... so I talked with a coworker and finally realized my mistake
I had been using an abstracted class to call the API and had glazed over the fact that under the hood the "request" method was actually reading the return stream into a string. The service returned the image png file as a stream, but the request method was converting this raw stream. Once I created a different request method I was able to get the png as a stream. From there it was relatively easy to use it as I intended: attaching the images as LinkedResources to an email that I then send out.
Original request method code
response = theRequest.GetResponse
Dim reader As StreamReader = New StreamReader(response.GetResponseStream)
lp_response.response = reader.ReadToEnd
New request code I wrote instead
lp_response.response = theRequest.GetResponse.GetResponseStream
VB.Net code to handle the stream (this is just a snippet where I'm building a List of LinkedResources to pass to my email function; just to give an idea of how I'm using it)
Dim document As Stream = LPApi.GetDocumentThumbnail(d("id").ToString)
Dim mediaType As String = Utils.GetContentType(Path.GetExtension(d("file_name")))
Dim lrDocument As New LinkedResource(document, mediaType)
lrDocument.ContentId = d("id").ToString
Thanks to everyone who commented. I'm pretty inexperienced when it comes to the deeper architecture of web requests/responses and data serialization. Any good learning resources would be helpful; otherwise I'll just keep Googling :)
It doesn't look like it's being encoded at all.
The IHDR chunk start is clearly visible and in plaintext at the start of the file.
It's probably not a good idea to use HttpWebRequest to download binary data, then convert the response to a string, just to try to convert that string back into binary data to save it to a file.
If you're getting an HttpWebResponse object, you should be able to use HttpWebResponse.GetResponseStream to get a stream for the image data. Then you should be able to copy the image data straight into your filestream using Stream.CopyTo.

x509Certificate - Save a binary signature in pkcs#7 format (.net c#)

I am signing some data with a self signed X509Certificate in c#. Signature results as a binary byte[]. I want to save this signature to a pkcs#7 format file with extenstion .p7b. When I save this using FileStream as required. It generates an invalid p7b file.
Can anyone help save this signature as a valid external file? Or point out if there is something wrong with the approach?
// EDIT: Adding the code as asked by Eugene Mayevski
// Open Store Location & fetch certificate
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
X509Certificate2Collection certifcates = store.Certificates;
X509Certificate2 certificate = certifcates[0];`
// fetch private key
string publicKeyString = certificate.GetPublicKeyString();
RSACryptoServiceProvider privateKey = certificate.PrivateKey as RSACryptoServiceProvider;
// get binary of data & sign it.
byte[] buffer = Encoding.Default.GetBytes("Sample data to sign. Although it would be a document.");
byte[] signature = privateKey.SignData(buffer, new SHA1Managed());
You are not generating a Cryptographic Message Syntax (CMS) message format which is defined in PKCS#7. You generate just the signature, which can be placed in the container format.
To create a CMS formatted message yourself, please take a look at the Microsoft documentation or use the C# version of Bouncy Castle.

loading response data into web view Titanium

I got response data from the web services, which is base64binary data.
I want to load this base64binary data into web view for titanium alloy [version 3.1.0.2].
The data base64binary is of pdf file.
Ti.API.info('Status is ::',xhrDocument.status);
var ResponseData = xhrDocument.getResponseXML().getElementsByTagName('GetDocResult').item(0).text;
var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,'pdfbinarray.pdf');
if(xhrDocument.status == 200){
var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, 'filename2.pdf'); file.write(xhrDocument.getResponseXML().getElementsByTagName('GetDocResult').item(0).text);
Titanium.API.info('file write');
Titanium.API.info(file.size);
}
The above code created filename2.pdf in my Documents directory. When I open the file using Adobe Reader, it says Adobe Reader could not open filename2.pdf because it is either not a valid file or has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).
Is the web service call returning ONLY the document, or is there additional data included in the response?
We have had success using a simpler method. If the service is simply returning the document, try changing line two to something more like this:
var ResponseData = xhrDocument.responseText;

FtpWebResponse GetResponse() gives "The remote server returned an error: (550) File unavailable (e.g., file not found, no access)."

I have a Win Form with a picture gallery that uses FtpWebRequest to upload pictures, but after changing to .Net 4.0 I suddenly get 550 error. The error occurs both when uploading files and listing directory.
As seen in my example-code I have implemented the MS solution from http://support.microsoft.com/kb/2134299.
I have checked the username, password and path - everything is correct.
Still, I get an error. I have skimmed Google for every solution without any response.
SetMethodRequiredCWD();
FtpWebRequest reqFTP = (FtpWebRequest)WebRequest.Create(new Uri(pPath));
reqFTP.Credentials = new NetworkCredential(Properties.Settings.Default.FTPUser, Properties.Settings.Default.FTPPass);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.KeepAlive = false;
FtpWebResponse respFTP = (FtpWebResponse)reqFTP.GetResponse();
Stream respStreamFTP = respFTP.GetResponseStream();
StreamReader streamReader = new StreamReader(respStreamFTP, Encoding.Default);
One approach I would recommend is to monitor the request/response exchange between the ftp-client and -server using e.g. Fiddler.
First, record a session in which the error does not manifest by manually using a third party client such as Filezilla to upload the file. Then, record another session with your program as the client. Comparing the exchanged messages may yield some insight to what is wrong.
Try to enable Network Tracing: http://msdn.microsoft.com/en-us/library/a6sbz1dx%28v=vs.100%29.aspx