Security of p12 (PKCS#12) certificate format - security

I have a question for the PKCS#12 format. The strange part is it requires to provide private key and the private key will be kept in the generated file.
Normally, when we apply a certificate from CA, we usually generate a CSR which contains the public key of a key pair I generated in advance. This public key will be put in the Certificate. So, when initiate the SSL connection, it will be used to encrypt and transmit the symmetric encryption key for the rest SSL channel communication. Since MITM don’t know the private key, so, they cannot get the symmetric encryption key. Only server has the private key can decrypt.
So, in any case, we should NOT put server’s certificate private key to others. Now, if I put the private key to PKCS#12, it seems totally breaks the rule.
I am working on a project related with a SSL pinning. A legacy lib requires to use PKCS#12 file format as the input. I feel it is very insecure to put the p12 certificate at client app.
Looking forward to your reply.

Related

How SSL Certificates (CA) are validated exactly?

I am searching the algorithm about how SSL validation process is performed, but almost everywhere, they explain the certificate validation step as "certificate is checked by client" or something like that, but I wonder what is the scenario behind this.
What I know is:
When the client receives a copy of the certificate that belongs to which website/server you wanna attempt to handshake, there are some indicators that shows the public information of webserver (I think this is for matching the entries in your cached certificate entries, which your browser has installed.)
Once the client matchs a cached-certificate with the webserver's one, it starts validating it. It uses the public key of cached-certificate to decrypt the signature of webserver's one.(? [Not sure this because public keys are used to "encrypt" the data, not decrypt. Also this step may be totally wrong.])
Once it decrypts, it compares the signature between cached one and webserver's one. If it is same, certificate is valid.
I also heard about chains. I really wonder how a chain is known, and how to determine if the webserver's certificate just belongs to a chain.(?)
How SSL certificates are checked by client? I need the answer as step by step and clarified. Thanks :)
Edit:
I think the public key here is used for "decrypting" instead of "encrypting". So a public key is not responsible for encrypting everytime, it can also decrypt and don't encrypt some data. The magic here is that since the public key decrypts here, if you want to fake the certificate, you should have that CA's private key to apply the changes as encrypted (because only private key can encrypt the data). But now, another question comes... What if we decrypt it using webserver's public key, then change the entries in the signature, then encrypt it again using our own private key (we generate it manually, it doesn't belong to server.), which actually make us behave like a CA; and finally overwrite the certificate to hold our own public key which is able to decrypt the data encrypted with our own private key?
There is differences between Encryption and Signature.
Public Key is used by the client to encrypt data that only the server can decrypt with the Private Key of the server.
Public Key is used by the client to verify the signature of the data send by the Server that can only be signed by the Private Key of the server.
When the client wants to access a server, the server send you a certificate containing a public key. The client usually the web browser will check in his integrated CA's list certificates if it contains it.
If it contains it, the client continue and get the CA(Certificate authority)'s that authorized this certificate.
If it not found but the verification of the signature pass, the client will get a warning saying that the certificate is probably self signed and can be malicious.
If the client can't verify the signature, it means the certificate is not valid.
for the chain of trust you can check wikipedia :
https://en.wikipedia.org/wiki/Chain_of_trust
you need to be in this chain of trust to be register in the web broswer integrated "database" of CA's.
Hope it answers your question, best regards,
M
Put it simple:
Private Key -> Decrypt and Sign
Public Key -> Encrypt and Verify
Certification Authority
Is the authority that signs and guarantees the authenticity of the certification. If you trust the CA, then you trust also its certificates.
It's the same for friends: if you have a friend that you trust and this tells you "I have a friend that I trust", then you also trust the friend of your friend.
Chain of Certificate Authority.
You can have multiple intermediate CA, for example, you can have
Root Certification Authority
Intermediate Certification Authority for WebServer signed by Root Certification Authority
Web Server Certificate signed by Intermediate Certification Authority for WebServer
Intermediate Certification Authority for signing code, signed by Root Certification Authority
Etc
Why?
Because in case one of the intermediate authorities is compromised you can revoke only its child certificates.
At the enterprise level, each CA has a different level of security, for example, the Root Certification Authority can be stored inside a safe and used only when there are two o more admins.
For the intermediate, instead, maybe only one Admin can manage it.
References
How SSL Works
How HTTPS Works
Wht digital certificates

SSL Certificate validation

I would like to know what are the exact steps of certificate authentication over HTTP.
I know this has been asked before, but from what I've read it's still unclear to me how it works.
When first contacting the secure site client will send its certificate
This will be his public key ( let's say a public_key.pem file begginging with ----BEGIN PUBLIC KEY---- )
Server will look whether this certificate has been signed by a trusted CA.
The server only has a list of certificates which it trusts (you configure this keystore when configuring SSL). That is where all private keys are stored. Is this equivalent to all the trusted CAs of the server?
The next step now is to take the public_key.pem and check whether any of the certificates in the keystore have signed it.
If the above process is accurate:
First question: A 'certificate' is a private key signed by another certificate ( or self-signed )
Second question: How exactly does a server validate that a public key was signed with a specific private key ( certificate ) ?
Third question: 'certificate' A can be used to sign another 'certificate' B, consequently 'certificate' B can be used to sign certificate C and so on. If my server has certificate A in its truststore, it means it will also trust public keys coming from certificate B and C ?
Edit based on answer below
My server has cert.pem and privkey.pem. The cert.pem ( x509 certificate ) has been signed by a trusted CA using its private key ( the 'signing' process involves the CA to do 'something' with its private key and sign my Certificate signing request ).
When SSL is negotiatied my server will send the cert.pem to the client ( in some form ). How does the client determine that my public cert was signed by a trusted CA. My truststore pb only contains other public certificates of trusted CAs, so it ends up checking whether my cert.pem was signed using only public certificates of trusted CAs.
This is is the part which is unclear - and I may be missunderstanding the whole process - can a client check if my x509 certificate is valid by just having an x509 list of certificates of trusted CAs?
When first contacting the secure site client will send its certificate
A client doesn't have to send a certificate. Judging from your question, it doesn't sound like you're asking specifically about client-cerificate authentication. In many sites, like if you go to google, stackoverflow, facebook, etc, the client / browser will not send a certificate.
A 'certificate' is a private key signed by another certificate ( or self-signed )
Not quite. A certificate contains a public key that is signed by the private key that corresponds to another certificate.
I think this is worth clearing up. A certificate itself will only ever contain the public key, or the "Subject Public Key Info" in x509 parlance. There is a corresponding private key to that public key that is stored separately from the x509 certificate.
There are some formats that "combine" the certificate and the private key in to a single file, but at this point it isn't a certificate anymore, it's a file containing a certificate - an example of this is PKCS#12. This is a format that can store as many certificates and private keys as needed.
A private key may not even necessarily be a file on disk - it could be in a Hardware Security Module, SmartCard, etc.
'certificate' A can be used to sign another 'certificate' B, consequently 'certificate' B can be used to sign certificate C and so on. If my server has certificate A in its truststore, it means it will also trust public keys coming from certificate B and C ?
Yes. This is called a certificate chain. A is the "root" certificate, B is an "intermediate", and C would be an "end-entity" or "leaf" certificate.
This is very common among HTTPS certificates by CAs. Certificates are never issued directly off the root, they're issued off the intermediate.
How exactly does a server validate that a public key was signed with a specific private key ( certificate ) ?
Well this makes the assumption that a certificate is a private key, which it isn't.
The server, as in the thing serving HTTPS, doesn't really care about the validity of the certificate. It's up to the client to decide if it should trust the certificate the server gives.
The server has the certificate and the corresponding private key. The server can validate that the public key and the private key belong together. How this is done depends on the key type, but the gist of it is, if you know the private key, you can fully reconstruct the public key from it. The server will validate that the private key's "public parts" match the certificate's public key.
The server will present the certificate to the client, like a browser. The browser will check many things, but at minimum it will check two important things:
Can the browser build a chain back to a certificate in the trust store. So the browser will look at the signer of the certificate, called the Issuer, and check if the issuer is in it's trust store. If yes, then the certificate is trusted. If no, it will see if that certificate has an Issuer, and loop all the way down the chain until it reaches the end of the chain, or when it finds something in the trust store. If it reaches the end, then the certificate was not issued by anyone it trusts.
That the certificate is valid for that domain. The certificate contains a Subject Alternative Name (SAN) which indicates what domains the certificate is valid for.
There are lots of other things that get checked, like expiration, revocation, Certificate Transparency, "strength" of the certificate - too many to list.
How does the client determine that my public cert was signed by a trusted CA.
Every client has its own trust store. Internet Explorer on Windows uses the Windows trust store, Google Chrome on macOS and Windows use the operating system trust store (Keychain, Windows Trust Store, etc).
The browser / client needs to build a trust path, as described above. How it does this is a bit complex, but it works out to the Authority Key ID attribute - if it exists, and the Issuer property of the certificate. It uses these values to find the certificate that issued it.
Once it finds the issuing certificate, it checks the signature on the certificate with the issuer's certificate public key.
That issuing certificate could be in the "root" trust store, and uses the public key in the issuing certificate to verify the signed certificate.
Your web server might (probably) send intermediate certificates along with the "main" (leaf) certificate. The client might use these intermediates to build a path back to a certificate that is in the root trust store. Intermediates can only be used as intermediates - you can't send an additional certificate saying "here's the root certificate, trust it".
can a client check if my x509 certificate is valid by just having an x509 list of certificates of trusted CAs?
Yes. That is the trust store. Every browser has / uses one. Firefox has their own trust store called NSS. Operating systems typically have their own trust store, too.

Authentication using digital signtures

I know a bit of authentication theory, but would like to know how is it really put in practice.
There are these software patches that must be distributed periodically. To ensure that only the genuine content reaches our users, we have been advised to sign our content before distribution.
The plan is to generate a Public-Private key pair. The patch would first be signed by our private key and recipients then authenticate the downloaded patch by using our public key. Our idea of signing is to generate a hash of the patch and encrypt the hash with our private key. The encrypted hash (signature) is to be bundled along with the patch before distribution.
We have been advised further that it is a good practice to get a digital certificate for our public key from a CA and post it on a certificate server in our premises. We are told that the CA would create this certificate using its private key. Our users are expected to download the public key certificate from our server and authenticate it using the public key of the CA. Thus our users would be confident that they have the right public key from us to authenticate the genuineness of the patch.
And finally the question:
How/where can the exact public key of the CA be downloaded for authentication of the public key certificate downloaded from our server?
In what formats are these certificates available? Are these plain text files or XMLs or ??
To answer your questions in order:
Using a browser and SSL. In that case you rely on the certificate store already in the browser. It may be a good idea to also publish the fingerprint of your own certificate. Note that you also distribute a certificate - or certificate chain - within your software. If the software download is trusted, then you may not even need an external Certificate Authority. But in that case you keep your private key of the CA very secure.
X5.09 certificates are created using ASN.1 DER encoding. DER is a binary encoding (and the textual ASN.1 definitions specifies the contents). Certificates are also often distributed in PEM format. This is a base 64 encoding of the binary certificate, with an additional header and footer.

Revoke pgp key using Bouncy Castle API

I want to revoke my PGP public key using Bouncy Castle API. I have generated a revocation certificate. But I wasn't able to find a way to revoke a public key using a revocation certificate.
How would I achieve it?
I found the method addCertification in PGPPublickey.java class but it is for adding a certificate and not for adding a revocation certificate.
I tried this method but it actually adds any revocation certificate to a public key, and the key is being revoked too. However, the public key should add only that revocation certificate that is generated from the corresponding private key.
You should add revocation certificate to your corresponding public key, and send this updated key to keyservers or other parties you are communicating to.
You're right on one count and wrong on another.
The Right: You've found the correct function for adding a revocation certificate to key. The addCertification function is what you should use to add your revocation certificate to a PGP Key.
The Wrong: That the function should not let you add a revocation certificate signed by someone other than the owner of the public key (which I have surmised is your assumption).
You can add any certificate signed by anyone to a PGP key. Whether the attached certificate has a relevant effect on the key is another matter.
For example, I could attach a revocation certificate generated by my secret key to your public key. However, does this mean your key has now been revoked? In short, no, it doesn't. This is because a public key can be revoked only by a revocation certificate signed by the corresponding private key, and it is up to the respective implementation (say, an encryption program like GPG) to verify this before saying your key is revoked.
In your case, your public key could have any number of revocation certificates attached to it. However, only a revocation certificate signed by the corresponding private key (which you presumably own, and is hopefully secret) will have the effect of actually revoking it.
That said, if you wish the fact that you have revoked your key to be communicated to the rest of the world, that is, via keyservers, you should first generate a revocation certificate signed by your private key, attach it to your public key (effectively revoking it), and then upload this revoked key to a keyserver. The keyserver will simply merge your key to the copy they have (if they have it), and propogate this key to other keyservers it knows. If all goes well, in a few days or longer, your revoked key should be available across the keyservers connected directly or indirectly to the keyserver you uploaded your key to.

can Digital certificate signature be copied? (ssl)

According to X.509 standard private key signature has to generate same encrypted message for ever?Am I right?
In order to avoid coping which data field in digital certificate will be changed?
they can't process the information of the user, but by coping the digital signature generated by private key and keeping along with the webpage attacker can say that I am certified by the CA and web browser will agree with that information.Is it true?
Version number,Serial number,Certificate algorithm identifier,Issuer name,Validity period,Subject name,Subject public key information Issuer unique identifier,Subject unique identifier,Extensions,Certification authority's digital signature.
These are the fields in digital certificate,if this fields don't change for ever,encrypted value will be same for ever.If I go to gmail it sends Encrypted digital certificate.If I use that Encrypted digital certificate in my webpage cant I say I am owner of gmail.but I can't use information send by the user since I won't have private key
A certificate must be signed by a CA in order to be considered as valid. The contents of the certificate is hashed, then encrypted by the CA's private key. Anyone can then validate whether the certificate is valid by decrypting the signature with the CA's public key, and verifying whether the hash matches.
The signature verifies that a particular name is associated with a particular public key - even if someone copied the certificate file verbatim, they wouldn't know the private key corresponding to that public key, and so they couldn't use it to impersonate the owner of the certificate.
I was wondering the same question.
Reading #Anon.'s answer led me to this: https://en.wikipedia.org/wiki/Transport_Layer_Security#Description
The handshake begins when a client connects to a TLS-enabled server
requesting a secure connection and the client presents a list of
supported cipher suites (ciphers and hash functions).
From this list, the server picks a cipher and hash function that it
also supports and notifies the client of the decision.
The server usually then sends back its identification in the form of a
digital certificate. The certificate contains the server name, the
trusted certificate authority (CA) that vouches for the authenticity
of the certificate, and the server's public encryption key.
The client confirms the validity of the certificate before proceeding.
To generate the session keys used for the secure connection, the
client either:
encrypts a random number with the server's public key
and sends the result to the server (which only the server should be
able to decrypt with its private key); both parties then use the
random number to generate a unique session key for subsequent
encryption and decryption of data during the session or
uses Diffie-Hellman key exchange to securely generate a random and unique
session key for encryption and decryption that has the additional
property of forward secrecy: if the server's private key is disclosed
in future, it cannot be used to decrypt the current session, even if
the session is intercepted and recorded by a third party.
It looks like in your forgery example (that I was wondered also) the client confirms the certificate successfully in paragraph 4. And then in paragraph 5 they fail to agree on session key as the server cannot read client's random number.

Resources