Chrome 58 deprecates self-signed certificates that omit the Subject Alternative Name (SAN). I use Mono.Security.X509 X509CertificateBuilder() to create a certificate for a Windows OWIN service on 'localhost' that enables the browser to communicate with a TWAIN scanner. The certificate currently only sets the Common Name so it is insufficient for Chrome 58.
What is the correct way to create a self-signed certificate that enables Chrome to communicate with the OWIN service on localhost, using Mono.Security.X509?
RSA subjectKey = new RSACryptoServiceProvider(2048);
X509CertificateBuilder cb = new X509CertificateBuilder(3);
cb.SerialNumber = GenerateSerialNumber();
cb.IssuerName = "CN=localhost";
cb.NotBefore = notBefore;
cb.NotAfter = notAfter;
cb.SubjectName = "CN=localhost";
cb.SubjectPublicKey = subjectKey;
cb.Hash = "SHA256";
byte[] rawcert = cb.Sign(subjectKey);
PKCS12 p12 = new PKCS12();
p12.Password = password;
Hashtable attributes = GetAttributes();
p12.AddCertificate(new X509Certificate(rawcert), attributes);
p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
return p12.GetBytes();
var san = new SubjectAltNameExtension(new string[0], new string[1] { "localhost" }, new string[0], new string[0]);
cb.Extensions.Add(san);
I tested this in Jexus Manager,
https://github.com/jexuswebserver/JexusManager/blob/master/JexusManager.Features.Certificates/SelfCertificateDialog.cs
Related
I have created websocket server and binded the self signed certificate with it , when websocket client fails to connect .
Eventviewer logs has this error.
"The TLS server credential's certificate does not have a private key information property attached to it. This most often occurs when a certificate is backed up incorrectly and then later restored. This message can also indicate a certificate enrollment failure."
Please find below code for creating self sign certificate.
var dn = new X500DistinguishedName("CN=" + Dns.GetHostName(), X500DistinguishedNameFlags.None);
var rsa = RSA.Create();
var req = new CertificateRequest(dn, rsa, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
// key usage: Digital Signature and Key Encipherment
req.CertificateExtensions.Add(new X509KeyUsageExtension(System.Security.Cryptography.X509Certificates.X509KeyUsageFlags.KeyEncipherment, true));
// Enhanced key usages
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection {
new Oid("1.3.6.1.5.5.7.3.1") // TLS Server auth
}, false));
req.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(1));
cert.FriendlyName = "Test";
string CertPath = Path.Combine(certPath, Guid.NewGuid() + ".pfx");
File.WriteAllBytes(CertPath, cert.Export(X509ContentType.Pfx, ""));
I'm writing an app that needs to make some HTTPs requests that use a client certificate. However, I can't find any documents on how to install the certificate and then load it for use. I know that you can use the certificate by making a HttpBaseProtocolFilter and adding a certificate but how do you load the certificate for use here? And if you have a .pfx file with your client certificate, how do you install it with your package?
Thanks in advance!
For what it's worth, I ended up figuring this out using a mix of the Portable.BouncyCastle NuGet package and some UWP APIs. Some sample (pseudo-ish) code for what I did is below:
// Asymmetric key pair
RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(
new KeyGenerationParameters(
new SecureRandom(new CryptoApiRandomGenerator()), 2048));
AsymmetricCipherKeyPair keyPair = keyPairGenerator.GenerateKeyPair();
// Create certificate
X509V3CertificateGenerator generator = new X509V3CertificateGenerator();
generator.SetSubjectDN("foo");
generator.SetIssuerDN("foo");
generator.SetSerialNumber(new BigInteger("12345").Abs());
generator.SetNotBefore(DateTime.UtcNow);
generator.SetNotAfter(DateTime.UtcNow + TimeSpan.FromYears(1));
generator.SetPublicKey(keyPair.Public);
BouncyCastleX509Certificate certificate =
generator.Generate(
new Asn1SignatureFactory("SHA1WithRSA", keyPair.Private));
// Create PKCS12 certificate bytes.
Pkcs12Store store = new Pkcs12Store();
X509CertificateEntry certificateEntry = new X509CertificateEntry(certificate);
string friendlyName = "Friendly Name";
string password = "password";
store.SetCertificateEntry(friendlyName, certificateEntry);
store.SetKeyEntry(
friendlyName,
new AsymmetricKeyEntry(keyPair.Private),
new X509CertificateEntry[] { certificateEntry });
string pfxData;
using (MemoryStream memoryStream = new MemoryStream(512))
{
store.Save(memoryStream, password.ToCharArray(), this.SecureRandom);
pfxData = CryptographicBuffer.EncodeToBase64String(memoryStream.ToArray().AsBuffer());
}
// Add the certificate to the cert store
await CertificateEnrollmentManager.ImportPfxDataAsync(
pfxData,
password,
ExportOption.NotExportable,
KeyProtectionLevel.NoConsent,
InstallOptions.DeleteExpired,
friendlyName);
// Read the UWP cert from the cert store
Certificate uwpCertificate =
(await CertificateStores.FindAllAsync(
new CertificateQuery { FriendlyName = friendlyName }))[0];
// Create the UWP HTTP client.
HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
filter.ClientCertificate = uwpCertificate;
HttpClient httpClient = new HttpClient(filter);
// Profit!
i have manually installed pfx extention certificate to my machine . How to get and pass in Windows.Web.Http.HttpClient
i tried following way but no luck
var myFilter = new HttpBaseProtocolFilter();
CertificateQuery certQuery = new Windows.Security.Cryptography.Certificates.CertificateQuery();
certQuery.FriendlyName = "TEST"; // This is the friendly name of the certificate that was just installed.
IReadOnlyList<Certificate> certificates = await Windows.Security.Cryptography.Certificates.CertificateStores.FindAllAsync(certQuery);
var client = new HttpClient(certificates[0]);
Can someone help me on this how to add manually installed certificate in httpclient ?
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = store.Certificates.Find(
X509FindType.FindByIssuerName, "TEST", false);
//Change FindType to your liking, it doesn't support FriendlyName,
//maybe use your method?
WebRequestHandler handler = new WebRequestHandler();
X509Certificate2 certificate = GetMyX509Certificate();
handler.ClientCertificates.Add(certificate);
HttpClient client = new HttpClient(handler);
There you have it. Maybe use your certificate for the Add method but I don't know if they're compatible.
App is about generating passes (Passbook App in Iphone) through C#.
I have downloaded Pass certificate and AppleWWDRCA certificate.
To generate pass I am able to generate pass.json and manifest.json.
But when I generate a PKCS 7 detached signature file using signing certificates and manifest.json it is not getting recognized by Passbook app in iphone.
I generated detached signature file using openssl in MAC and that is working fine and getting installed in Passbook.
I have downloaded pass certificate and AppleWWDRCA certificate
Can anyone help me in step by step procedure of creating signature file in c# and methods to be used
I have stored both the certificates in local folder not in windows local store. I have tried in windows local store before but it was not working.
below is the method used for signature,
X509Certificate2 card = GetCertificate(); //Fetches the pass certificate
X509Certificate2 appleCA = GetAppleCertificate(); //Fetches the AppleWWDRCA certificate
byte[] manifestbytes = Encoding.ASCII.GetBytes(manifest);
ContentInfo contentinfo = new ContentInfo(manifestbytes);
SignedCms signedCms = new SignedCms(contentinfo, true);
var signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber,card);
signer.Certificates.Add(new X509Certificate2(appleCA));
signer.IncludeOption = X509IncludeOption.WholeChain;
signer.SignedAttributes.Add(new Pkcs9SigningTime());
signedCms.ComputeSignature(signer);
signatureFile = signedCms.Encode();
return signatureFile;
I have created an open source C# library for generating these passes.
https://github.com/tomasmcguinness/dotnet-passbook
This is the code I use perform the signing of the files (it uses BouncyCastle)
// Load your pass type identifier certificate
X509Certificate2 card = GetCertificate(request);
Org.BouncyCastle.X509.X509Certificate cert = DotNetUtilities.FromX509Certificate(card);
Org.BouncyCastle.Crypto.AsymmetricKeyParameter privateKey = DotNetUtilities.GetKeyPair(card.PrivateKey).Private;
// Load the Apple certificate
X509Certificate2 appleCA = GetAppleCertificate(request);
X509.X509Certificate appleCert = DotNetUtilities.FromX509Certificate(appleCA);
ArrayList intermediateCerts = new ArrayList();
intermediateCerts.Add(appleCert);
intermediateCerts.Add(cert);
Org.BouncyCastle.X509.Store.X509CollectionStoreParameters PP = new Org.BouncyCastle.X509.Store.X509CollectionStoreParameters(intermediateCerts);
Org.BouncyCastle.X509.Store.IX509Store st1 = Org.BouncyCastle.X509.Store.X509StoreFactory.Create("CERTIFICATE/COLLECTION", PP);
CmsSignedDataGenerator generator = new CmsSignedDataGenerator();
generator.AddSigner(privateKey, cert, CmsSignedDataGenerator.DigestSha1);
generator.AddCertificates(st1);
CmsProcessable content = new CmsProcessableByteArray(manifestFile);
CmsSignedData signedData = generator.Generate(content, false);
signatureFile = signedData.GetEncoded();
I hope this helps.
Working with certs is all still new to me.
I am trying to load a p12 cert file (I think is is called a self signed cert) for use with a channel factory. This is a C# program in VS2010 and a WFC service reference. Below are the methods I have tried and the errors I am receiving. The last bit of code is VB.net code, which runs without error. I think this indicates that the path and password to the p12 file are correct.
//Create the binding and channel
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;
EndpointAddress serviceAddress = new EndpointAddress("http://myendpoint");
ChannelFactory<ServiceName> channelFactory = null;
channelFactory = new ChannelFactory<ServiceName>(binding, serviceAddress);
//try to add the cert - Error: Object reference not set to an instance of the object. I've tried all available X509KeyStorageFlags
channelFactory.Credentials.ClientCertificate.Certificate.Import(#c:\path\to\file\fw.mycert.com.p12", "password", X509KeyStorageFlags.PersistKeySet);
//try to add the cert - Error: The specified network password is not correct. I've tried all available X509KeyStorageFlags
//rawCertificateData does contain 2000+ bytes
X509Certificate2 certificate = new X509Certificate2();
byte[] rawCertificateData = File.ReadAllBytes(#"c:\path\to\file\fw.mycert.com.p12");
channelFactory.Credentials.ClientCertificate.Certificate.Import(rawCertificateData, "password", X509KeyStorageFlags.DefaultKeySet);
//This works in vb.net with the same path and password
Dim cert As New X509Certificate2("c:\path\to\file\fw.mycert.com.p12", "password")
request.ClientCertificates.Add(cert)