Can PEM_read_X509 function read in a CA cert file with private key properly? is it intelligent enough to handle the private key section? Or it will error out if the .pem file contains the private key?
TLDR: YES
Almost all OpenSSL PEM_read[_bio]_XYZ functions will accept a file (or equivalent) containing other data before and/or after the PEM block of type XYZ, and ignore the other data as long as it's not on the same line(s). This is designed to allow 'comments' that describe the PEM data, but also works for other types of PEM data or just arbitrary data not related to the PEM data at all. In particular PEM_read_X509 will read the first block of type CERTIFICATE, X509 CERTIFICATE, or TRUSTED CERTIFICATE and ignore anything and everything else, including a private key block.
Similarly PEM_read_[algo_or_PKCS8]PrivateKey will read the first block of type [ENCRYPTED|RSA|DSA|EC] PRIVATE KEY and ignore everything else, but fail if you tried to read a specific algorithm and the (first) private key block found was a different type. (It also fails, of course, if a valid block is found but is encrypted by a password and you don't provide the correct password either as an argument or via a callback. And if no valid block is found.)
I'm not sure if by 'CA cert' you mean a cert for a CA, or a cert issued by a CA and for an end-entity like your webserver or mailbox. Except for a personal/local or test CA you or a colleague or your organization set up, most ordinary users should have the certs for one or more CAs but never their privatekeys. And if someone responsible for a real CA like say LetsEncrypt was asking such basic questions on Stackoverflow I would be greatly alarmed and worried over the competence and thus security of that CA.
Related
I'm trying to learn more about certificates, and one of the things that I'm struggling to wrap my head around are the Basic Constraints. I was wondering if anyone that has experience working with certs could help me understand what the Basic Constrains are, how they work, and what they are used for.
I've tried doing my own research, and self educating.
https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.9
The basic constraints extension identifies whether the subject of the
certificate is a CA and the maximum depth of valid certification
paths that include this certificate.
...
BasicConstraints ::= SEQUENCE {
cA BOOLEAN DEFAULT FALSE,
pathLenConstraint INTEGER (0..MAX) OPTIONAL }
It's just a marker of "is this certificate allowed to issue other certificates?" (cA:TRUE for yes, cA:FALSE for no). When the answer is yes, it can optionally limit the number of tiers of "child CAs", 0 meaning the CA certificate isn't authorized to issue certificates that say cA:TRUE, 1 meaning the CA can issue certificates that say cA:TRUE, but those CAs can't, etc.
The technical questions about certs are answerable from IETF RFC 5280, or from ITU-T X.509 (from whence the name "X.509 certificate")
I am trying to generate X509 certificates in C# code (using the class X509Certificate2) and upload these certificates to an Azure Key Vault. When I try to upload them (programmatically or via the Azure Portal in a browser), I get the following error message:
The specified X.509 certificate content is invalid. Error: one or more x.509 properties are invalid.
How can I debug what is wrong with my certificate generation? Is it documented what combinations of X509 properties are acceptable? If so, where can I read about it?
Output from certutil -dump foo.pfx:
> certutil -dump E:\Raven\Certificates\test2.pfx
Enter PFX password:
================ Certificate 0 ================
================ Begin Nesting Level 1 ================
Element 0:
Serial Number: 86ae932f199f419115e8087f3f0cb6df747bd2adf966d46aab194f4283849635
Issuer: CN=intermediate CA
NotBefore: 24-01-2022 11:22
NotAfter: 25-01-2022 11:22
Subject: O=foo, CN=bar
Non-root Certificate
Cert Hash(sha1): a700464f1708cec627eabcd007ef574d1f0fc140
---------------- End Nesting Level 1 ----------------
Provider = Microsoft Software Key Storage Provider
Private key is NOT plain text exportable
Signature test passed
CertUtil: -dump command completed successfully.
In my case it turned out to be two things:
The serial number. I was using RandomNumberGenerator.GetBytes(32) to generate serial numbers, which was apparently bad. The vault is happier if I do Guid.NewGuid().ToByteArray().
The flags (enum X509KeyUsageFlags). I tested several combinations of flags, and it turns out that whenever I use the flag X509KeyUsageFlags.KeyEncipherment the vault will reject the certificate.
I don't know why. I suppse that if you use the KeyEncipherment flag, there is some other invariant that the certificate needs to obey.
In any case, when I fix the serial numbers and remove this flag, it appears that the vault accepts my certificates.
If I fix only the serial number but keep the KeyEncipherment flag, I get this error message:
Unsupported key operation(s): "wrapKey", "unwrapKey". Supported values are "sign", "verify".
I'm a newbie with encryption but I have a few questions. I know the subject is complicated, but I'm not asking specifically for the standard but what could work, that is to say, what should be secure, even if less than real RSA methods, even if it is not the standard but should be securized. It's questions about asymmetric encryption more generally.
1) Which private key is used to sign a Certificate ? Is it the private key related to the public key of the organization, or the private key of the autority. I think it's the first one because in Java, when I try to sign with a private key that is not the pair of the public key in the certificate, it fails (Edit. I know it may depend of the content of the "Certificate", and that a signature just sign a chunk of bytes).
If the private key of the organization is used to sign a Certificate: it means that the authority can't sign the certificate (it doesn't has the private key of the organization): does that mean that the signature is provided by the organization ?
2) It's related to question. 1 but do authority need a private key to generate certificate ? Like 2-pass signature, use the two keys to verify the signature. If yes, for which purpose specifically ?
Also if the autority doesn't need to have a private key, is it sufficient, for checking if a certificate is valid, that the certificate is right AND the authority contains the given public key in the database (or at maximum check byte by byte if the certificate in the database is the same that the one-to-check), on the assumption of the private key can not be deduced fro mthe public key ?
3) I'm confused with public/private and encryption/decryption relation. What I've seen and learn is that private encryption key is used to sign and private decryption key is used to securize communications, also we can say that encryption/decryption is just a term of langage and it has no other reality than conversion to a direction or the other. BUT in Java to sign a document with the class Signature you provide a private key to generate the signature (if i'm correct). On the other hand you use it to decrypt communications, right ? So you use it for encryption and decryption. Is it ok. to do so or do we need 2 pairs of keys to do securized communication, one for certificates and one for communications ?
4) Off-topic but I think the RSA keys are asymmetric but provide the same mathematical properties and also have a sort of symmetry, so we can encode with decryption key and reciprocally.
Is this example correct, just for curiosity:
to the left: encrypt with private key
to the right: encrypt with public key
... <-> messageP2 <-> messageP1 <-> message <-> messageR1 <-> message R2 <-> message R3 <-> ...
Thanks
the whole point of certificates is trust in a PKI (public key infrastructure)
a key in a PKI is allways a key pair. the private part is always kept secret by the owning party
there are way too many parties that everybody knows the public key of everybody else
everybody knows the public key of the CA (or a known CA has to sign the key of a sub-CA, if you want multiple layers of CAs)
everybody gets their public key embedded into a certificate signed by a CA
if you now want to communicate with someone, you ask for their certificate ... since you don't know them yet (or to be precise, you don't know their key yet) you can't be sure that you are communicating with the intended party
they send over their certificate...
now you can check the chain of trust:
their certificate is signed by someone ... is that someone trustworthy AND is the signature valid?
is that someone trustworthy? a quite simple question: is that someone a trusted CA that may sign certificates for the intended party? in other words: can we find the siging CAs certificate in our list of trusted CAs, or did another trusted CA sign their cert as a CA cert?
is the signature valid? can be tested if the signing CAs pub key is known
now what if we know this CA and trust it? ... everything is ok... but what if we don't know that CA? usually our communication partner can provide the certificate of that CA (since certificates are public, in other words, not secret)
now we can repeat ... is the presented CA cert signed by someone trustworthy and is the signature valid?
the whole point of this is: it's not required to have a huge database with all the public keys, and the communicating parties are able to verify identities on their own as long as they can verify the certs
so with this in mind ...
1) the CAs private key is used to sign a cert. The signature on a cert is equal to the statement "the signer can be held accountable for the validity of all the values in the cert"
2) the CA signs the certificate ... signing here is an operation that requires a key... just having the cert in a database at the CA does not suffice ... take into account that the identity of the certificate holder needs to be checked while there is no way of communicating with the CA
3) to lighten that confusion
sign / decrypt ... private key
verify / encrypt ... public key
usually cryptosystems for signatures and encryption are different ...
RSA is the unicorn here, it can be used for both
the idea behind a certificate is that you can embed public keys, and bind them to an identity in a way that a common trusted CA is enough for two otherwise unknown parties to safely exchange their keys
4)
from the math point of view ... yes ...
the RSA operation is X^e mod N = C ... C^d mod N = X
with X = plaintext ... C = ciphertext ... N,e,d rsa-parameters
the principle behind RSA is that e*d mod phi(N) = 1
therefore
(X^e)^e = X^(e*e)
(X^(e*e))^d = X^(e*e*d) = X^(e*1) = X^e
(X^e)^d = X^(e*d) = X^1 = X
The purpose of have a certificate issued by an authority is that the authority is certifying that the information in the key is accurate. In order for that certification to be verified, the certificate must be signed using a private key that is only known to the certifying authority.
Operating System Win server 2012 R2
I am creating Root CA in Active directory certificate service.
I am using my custom RSA KSP, (Key Storage Provider) based on CNG(Cryptographic Next Gen. API).
My certificate is created in c:\windows\system32\certsrv\certenroll\mycert.crt
All seems well, I open and see my certificates, it seems ok and signatre is also ok.
.........................................
My certsvc is not starting is is saying.
Signature is not valid.
The cryptographic sinature is invalid, oxc000a000.
Also, .crl is nor created.
When I verify my certificate using
certutil -verify
is says..
cannot check leaf certificate revocation status.
I am not able to check, what's going wrong.
Can I get some hint, what's going on with my CA.
Thanks In Advance.
I figured it out, just after posting the question.
When Microsoft ROOT CA is passing signature, in CNG signinig api.
It is expecting that we must prepend the NID, or oid and then sign it.
and return the same signed bytes.
Our setup includes a WCF service and a number of clients written by us. Some of the clients include Silverlight applications, whereas others include Web and Windows applications.
I (think) I would like to authenticate clients based on X.509 certificates. Typically you would install a private key on the client to encrypt (aka digitaly sign) the messages. The server can the use the clients public key to de-crypt it to ensure the message has not been changed and prove the message is from who we expect (aka authenticated).
I dont want to install a certificate on a client machine. Its a hassel to deploy, and we cant really ask our clients to do it. I was speaking to someone the other day who sugested embeding the cert in a client assembly, reading it and using that. Is that possible?
It would be great if someone could point me to an example.
Thanks in advance,
David
Yes, you can load X509certificate2 by passing a certificate byte array with a password like
var certificate = new X509Certificate2(theByteArrary, "password");
To get the certificate byte array, you can simply copy paste the contents in .pfx file, which is a combination of .cer (public key) and .pvk (private key)
and then you can load this certificate on your client by doing:
var channelFactory = new ChannelFactory<IYourService>();
channelFactory.Credentials.ClientCertificate.Certificate =
clientCertificate;
If you use auto-generated client proxy, or you prefer configure the certificate via .config file then you might want to have a look at this from codeproject
Here is a suggestion. Could also be tweaked to use an embedded certificate.
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx