CryptographicException while loading X509Certificate2 from PFX file programatically: - x509certificate2

In the tmpAEC4.pfx file, I have the content representing the certificate set at the bottom of this message. When I try to instantiate X509Certificate2 :
var data = File.ReadAllBytes(#"C:\Temp\tmpAEC4.pfx");
new X509Certificate2(data, "9G8U922PWY");
I receive the following exception
(System.Security.Cryptography.CryptographicException: 'An error occurred during encode or decode operation.):
The password is correct, as if I import the pfx manually, it works. Any idea?
Certificate:
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

The problem is that you are reading Base64 text file as binary. You need to read the text and then convert Base64 text to byte array:
String base64 = File.ReadAllText(#"C:\Temp\tmpAEC4.pfx");
Byte[] data = Convert.FromBase64String(base64);
var cert = new X509Certificate2(data, "9G8U922PWY");
File class belongs to System.IO namespace;

Related

Its posible decode a .p12 file with asn1js and pki.js?

p12 file from where I want to extract public and private keys and the x509 certificate with pki.js But my .p12 file has a password how can I decode it. For example:
const asn1js = require("asn1js");
const pkijs = require("pkijs");
const Certificate = pkijs.Certificate;
let path = __dirname + "/file.p12";
let file = fs.readFileSync(path);
const asn1 = asn1js.fromBER(file);
//What do I do with the password for the .p12 file?
const certificate = new Certificate({ schema: asn1.result });
There is an example of doing this in the PKIjs repository; https://github.com/PeculiarVentures/PKI.js/tree/master/examples/NodePKCS12Example

Remove the WebKitFormBoundary in C#

I am working on the server that receives a file stream uploaded by multipart uploader.
But I got an additional WebKitFormBoundary.
If I remove it manually, it will work. So I tried the following code:
var fileStream = File.Create(#"C:\Users\myname\Desktop\myimage.png");
stream sr = new streamReader(myStream);
string myText = sr.ReadToEnd();
string newText = myText.Substring(myText.IndexOf("‰")); // remove header
byte[] byteArray = Encoding.ASCII.GetBytes(newText);
MemoryStream data = new MemoryStream(byteArray);
data.CopyTo(filestream);
If I use the above way to convert it to string, remove boundary and convert back to stream
the first character "‰" will become "?"
(ie. So ‰PNG will become ?PNG and the file becomes not readable.)
Any suggestions?
Where could I possible got wrong?
Thanks
This drove me nuts. Finally understood that if you have access to the request, you can access just the contents (with no header) like this:
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var file = await provider.Contents[0].ReadAsStreamAsync();
Hope this helps you, or someone with the same issue.
I have got the same issue but after investigating several blogs with applied several solutions, I got final working one. Please follow below code approach to fix it.
MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes(filePath));
StreamReader streamReader = new StreamReader(memoryStream, Encoding.Default, true);
memoryStream.Seek(0, SeekOrigin.Begin);
string fileString = streamReader.ReadToEnd();
string fileData = fileString.Substring(0, fileString.IndexOf("\r\n\r\n") + 4);
string finalData = Regex.Replace(fileString, fileData, "");
var fileDataArr = Regex.Split(fileData, "\r\n|\r|\n").ToList();
var resultData = Regex.Replace(finalData, fileDataArr[0] + "--", "");
byte[] buffer = Encoding.Default.GetBytes(resultData);
Steps:
Convert your filedata into memory stream which can be used to read file content.
Use StreamReader to read file content and remove webkitformBoundary Header with default Encoding format.
Code To remove first 4 lines including webkitformBoundary from Top.
Code to remove webkitformBoundary from Footer.
Convert the string into Byte Array with default encoding format to maintain the file Encoding format.
Example:
WebKitFormBoundary Header
------WebKitFormBoundaryL1NUALe5NDrNt9S0 <br/>
Content-Disposition: form-data; name="userfile"; filename="BRtestfile1.pdf" <br/>
Content-Type: application/pdf <br/>
WebKitFormBoundary Footer
------WebKitFormBoundaryL1NUALe5NDrNt9S0-- <br/>

How to attach a created file to mail mvc

As each user runs through my application I hold their data and dump it into a report as follows, which at the end is created into a pdf document and is later automatically downloaded on the users side(client-side). I now want to attach this document to an email and have it forwarded to them. This is where I have troubles with the attachment.
Code as follows:
ReportDocument rd = new ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports/PP_RentalAgreement.rpt")));
rd.SetParameterValue("rent_agree_no", _1);
rd.SetParameterValue("r_initial", _2);
rd.SetParameterValue("r_f_name", _3);
rd.SetParameterValue("r_l_name", _4);
rd.SetParameterValue("r_id_no", _5);
rd.SetParameterValue("r_lic_no", _6);
rd.SetParameterValue("r_tel", _7);
rd.SetParameterValue("r_cell", _8);
rd.SetParameterValue("r_fax", _9);
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
Stream st = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
st.Seek(0, SeekOrigin.Begin);
if (ModelState.IsValid)
{
var m_message = new MailMessage();
m_message.To.Add(new MailAddress("JoeSoap#TextMail.com"));
m_message.Subject = "Pink Panther - Invoice";
m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf"));
using (var smtp = new SmtpClient())
{
await smtp.SendMailAsync(m_message);
return RedirectToAction("Index");
}
}
I am getting an error on this line : m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf")); saying The specified content type is invalid.
Someone suggested to me that I should specify a path however I am not actually saving this file anywhere
How am I able to allow the file to be attached and send it to the recipient?
The System.Net.Mail.Attachment class constructor with 3 overloads consist of these parameters:
public Attachment(System.IO.Stream contentStream, string name, string mediaType)
Hence, you're assigning name and content type in reversed order, which causing invalid content type problem at this code:
m_message.Attachments.Add(new Attachment(st, "application/pdf", "Invoice.pdf"));
The correct way is putting the file name as second argument like example below:
m_message.Attachments.Add(new Attachment(st, "Invoice.pdf", "application/pdf"));
Or using MediaTypeNames for content type setting:
m_message.Attachments.Add(new Attachment(st, "Invoice.pdf", MediaTypeNames.Application.Pdf));

Uri is not supported when saving pdf in server folder with nreco pdf generator

I have the following code:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
htmlToPdf.PdfToolPath = "~/files/";
htmlToPdf.GeneratePdf(template);
Which throws the following error:
Uri is not supported when saving pdf in server folder with nreco pdf generator.
You will need to set a regular path to your file system like e.g. "C:\temp\myfolder\". Or use a . instead of ~ and backslashes:
htmlToPdf.PdfToolPath = ".\\files\\";
If NReco is able to deliver you an byte-array or a stream you should prefer this instead of a file and return it directly.
UPDATE:
After takeing a look into the documentation of NReco all you need to do is following:
var htmlToPdf = new NReco.PdfGenerator.HtmlToPdfConverter();
htmlToPdf.PdfToolPath = "<CORRECT_PATH_FOR_TOOL>";
var output = htmlToPdf.GeneratePdf(template);
System.IO.File.WriteAllBytes("<OUTPUT_PATH>", output);
This should create your pdf in the OUTPUT_PATH.
#OlaFW thanx for your effort.
I got my answer.
var pdfBytes = htmlToPdf.GeneratePdf(template);
string filePath = "/files/Myfile.pdf";
string Url = System.Web.Hosting.HostingEnvironment.MapPath(filePath);
System.IO.File.WriteAllBytes(Url, pdfBytes);

How do I use Bouncy Castle to read an App Store In App Purchase receipt? (PKCS7)

I have a receipt in PKCS7 that I obtained from my iOS app. Apple says this is a PKCS7 structure, and within that, is information regarding past recurring purchases.
I have the raw receipt here, encoded in Base64.
I've sent this payload, with my secret key, to Apple and got this response. Based on WWDC videos, and documentation, I believe I should be able to read this receipt directly, and without sending it to apple.
I'm guessing that PEMReader in BC is the correct starting point parse it, however I'm not sure how to actually use it. I've scanned the BC source code for the strings "PKCS", and looked at unit tests, however all I ever see are casts from PEMReader into another format.
using (var stream1 = new MemoryStream(receipt.Data))
using (var stream2 = new StreamReader(stream1))
{
var pp = new PemReader(stream2);
pp.ReadObject();
}
Question
How do I use Bouncy Castle to verify a raw receipt payload generated from Apple Store?
Note to self: I intend to use this to inspect the actual binary to see if ApplicationUsername is included in the receipt, yet for some reason isn't returned in the JSON result when posting the server. (Bug on Apple's side?)
I've made this using Java 7 and BouncyCastle 1.56.
For the code below, consider that pemString is the PEM string you provided. But I had to make some modifications:
format (break lines for every 64 characters) - I've made a small program to do that
include BEGIN and END headers
So my PEM looks like:
-----BEGIN PKCS7-----
MIIv5gYJKoZIhvcNAQcCoIIv1zCCL9MCAQExCzAJBgUrDgMCGgUAMIIfhwYJKoZI
hvcNAQcBoIIfeASCH3Qxgh9wMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQEC
AQEEAwIBADALAgELAgEBBAMCAQAwCwIBDwIBAQQDAgEAMAsCARACAQEEAwIBADAL
....
gdTu2uzkTyT+vcBlaLHK1ZpjKozsBds7ys6Q4EFp7OLxtJTj7saEDYXCNQtXBjwl
UfSGvQkXeIbsaqSPvOVIE83K3ki5i64gccA=
-----END PKCS7-----
For the code below, I followed the definition in Apple's doc:
ReceiptAttribute ::= SEQUENCE {
type INTEGER,
version INTEGER,
value OCTET STRING
}
Payload ::= SET OF ReceiptAttribute
Code:
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DLSequence;
import org.bouncycastle.asn1.DLSet;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
String pemString = // PEM String as described above
PemReader reader = new PemReader(new StringReader(pemString));
PemObject pemObject = reader.readPemObject();
reader.close();
CMSSignedData s = new CMSSignedData(pemObject.getContent());
byte[] content = (byte[]) s.getSignedContent().getContent();
ASN1InputStream in = new ASN1InputStream(content);
// Payload: a SET of ReceiptAttribute
DLSet set = (DLSet) DLSet.fromByteArray(in.readObject().getEncoded());
int size = set.size();
for (int i = 0; i < size; i++) {
// ReceiptAttribute is a SEQUENCE
DLSequence seq = (DLSequence) set.getObjectAt(i);
// value is the third element of the sequence
DEROctetString oct = (DEROctetString) seq.getObjectAt(2);
ASN1Object obj = readObject(oct.getOctets()); // *** see comments below ***
}
in.close();
// readObject method
public ASN1Object readObject(byte[] b) throws IOException {
ASN1InputStream in = null;
try {
in = new ASN1InputStream(b);
return in.readObject();
} catch (Exception e) {
// if error occurs, just return the octet string
return new DEROctetString(b);
} finally {
in.close();
}
}
Variable obj will be the content of the ReceiptAttribute, and it can vary a lot - I've seen DERIA5String, DERUTF8String, ASN1Integer and many others. As I don't know all possible values of this field, I think it's up to you to check each value.

Resources