I would like to store public cert in a database, but I need an attribute of the public cert to index the public certs in the database. I would like to make this a unique field.
Is the finger print of a public cert unique?
The fingerprint is unique (for all practical intents); two different certificates should never share the same hash. For example, per the Windows X509certificate2.thumbprint documentation:
the thumbprint is a unique value for the certificate, it is commonly used to find a particular certificate in a certificate store.
Per the OpenSSL documentation:
Because of the nature of message digests the fingerprint of a certificate is unique to that certificate and two certificates with the same fingerprint can be considered to be the same.
Note the fingerprint is not part of the certificate. Rather, it is calculated by taking a cryptographic hash of the entire certificate (including the signature). Different cryptographic implementations may use different hashing algorithms to compute the fingerprint, and thus provide different fingerprints for the same certificate. (For example, the Windows Crypto API computes the SHA-1 hash of the certificate to compute the thumbprint, whereas OpenSSL can generate the SHA-256 or SHA-1 hash.) You will thus need to ensure that clients using the database fingerprint are using the same API, or a consistent hashing algorithm.
In theory, a duplicate fingerprint shared by multiple certificates would require a hash collision. The probability of such an event occurring by chance is astronomical. Intentionally generating such a certificate pair would require a successful preimage attack on the underlying hash function, an attack not known to be feasible on SHA-1 (see Preimage Attack).
Related
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.
Newbie question: some vendors propose solution like generating dynamic certificates to allow user who haven't classic certificate to sign documents. But why not just generate private/public keys alone instead of bothering with certificate format ?
The purpose of the (public key) certificate is to bind the public key to the identity of its subject (i.e. the owner/entity associated with the key pair), and possibly various attributes telling you what the certificate may be used for. (You may be interested in this question on Security.SE.)
You always sign with the private key (not the public key or the certificate), but the public key or certificate are often attached with the signed document.
If you have an explicit list of public keys you know and can link independently to a user, you don't need a certificate.
The certificate allows third parties (who have signed the certificate) to assert the binding between the identifier and the public key. Even if you don't know that identity in advance, you can link the signature to the signer's identity as long as you trust the entity that signed the certificate.
Dynamically generated certificates may not be very useful in this case, unless you trust the party that generates the certificate dynamically (I'm not sure if you meant the tool itself or perhaps a website that you would also know).
Often, X.509 certificates will be used just to attach to that signature, because the tooling requires it, whereas you may be able to match the public key against an identity you know directly in the tool with which you verify the signature. Sometimes, it's also just done in anticipation of a case where it will be useful one day.
For example, if you publish your own artifacts to the central Maven repository, you will be required to sign it with your PGP certificate (often only referred to as the PGP public key). Yet, no verification of the certificate is made at all during the process (PGP certificate with only its self-signed signature is good enough). This makes this process relatively pointless in this case, but makes it possible to be stricter in which artifacts you want to use, if you're able to verify those certificates later on.
It's the same but you need a third party to consent that private key belongs to whom ever you think it belongs to.
Signing proves first of all authorship (or approval) of the document by some person. And the key alone won't prove anything. This is what the certificate is needed for - some certificate authority signs the certificate of the user and certifies that the keypair belongs to the person (or legal entity) to which the certificate is issued. The reader of the document can ensure that the signature is valid not by just computing the signature itself, but also by validating the certificate and seeing the name of the certificate owner.
I don't quite understand what vendors can issue certificates dynamically - issuing certificate in such way that they are not self-signed (and self-signed certificates make little sense in context of document signing) requires that the private key, used for signing the certificate, should be embedded into software of those vendors, and as such it's also prone to misuse.
I've been reading a few sites on the internet on how SSL works, but I don't understand how exactly it makes things secure. Probably because I don't understand completely how it works.
Let me begin with the core idea of SSL. It is used to encrypt HTTP connections, but for the client and the server to communicate with encrypted data, surely an encryption key needs to be shared. If someone is eavesdropping on your connection, wouldn't they just be able to grab this key and continue listening while decrypting the data? I can image this technique would work if we're talking about a long term connection, but HTTP requests are often completed within half a second.
Let's assume this is somehow taken care of. The other utilisation of SSL is to verify if a server is exactly who it says it is. What prevents a rogue server from faking a certificate signed by a root certificate provider? In none of the descriptions I've read, the browser actually contacted one of these authorities to verify the certificate with them. Let's assume the certificate is encrypted with a private key by the root certificate authority, how is the browser able to verify the data in this certificate without knowing the decryption key? Or is the decryption key different from the encryption key?
One solution to these problems I can imagine is if the certificate and key are only sent once and are stored along with the domain and IP address in your browser.
Thanks for explaining in advance.
First, some basic concepts about public key cryptography:
This relies on a pair of keys. One is the public key (which can be distributed); the other one is the private key, intended to be kept private.
You can encrypt data using the public key, which the private key can decrypt/decipher.
You can sign data using the private key, and this signature can be verified using the public key.
To make sure you're communicating with the right entity, you need to bind an identity to a key-pair. This is where certificates come in. A public key certificate is a signed document containing both the subject's identity (name) and the subject's public key.
For example, the certificate for www.google.com contains its public key and the name www.google.com. It has been signed using the private key of a Certification Authority (in this case, Thawte). In the X.509 terminology (the common standard for certificates used for HTTPS), the CA is the issuer of the certificate, and it puts its name in the certificate too, alongside the subject's name, the subject's public key (and other attributes). The issuers are meant to verify the identity of who they issue a certificate for.
The reason you don't necessarily see your browser fetching information from the CAs is that a number of commercial (or governmental) CA certificates are bundled with your browser or your OS. You trust them by default. This can be considered as a "leap of faith", but any trust mechanism needs this sort of starting point.
You may want to read more about the TLS handshake, but in short:
The client gets the server's public key by looking into its certificate.
The client encrypts a secret using this public key and sends it to the server. The details of this depend on the cipher suite (could be Diffie-Hellman based), but the result of this should be a list of shared encryption keys (using symmetric cryptography, not public key cryptography).
These shared keys are only known to the client and the server, and they're used for encryption/decryption.
For SSL/TLS to be secure, you need at least 3 points:
A suitable cipher suite, and a successful handshake.
Verifying that the client trust the server certificate (typically, via a known CA in the PKI model).
Verifying that the certificate belongs to the server the client intended to contact (hostname verification).
(This is the case for the vast majority of usages of SSL/TLS (in particular HTTPS), but it's also possible to use other mechanisms than X.509 certificates with TLS, for example OpenPGP certificate or Kerberos cipher suites. This is less common as far as I know.)
In order to encrypt a connection you have to agree to some shared secret. This can be done with diffie-hellman. To prevent man in the middle attacks, so you also need a certificate mechanism.
For encrypting or signing (certificates) you can use asynchronous keys. This means you have two different keys (public and private key) to encrypt/decrypt. Usually you encrypt your data with a public key, and someone can decrypt it with his private key. Signing is done with your private key, and someone else can check it with a public key.
So you see, faking a certificate is not that easy, since you don't have the private key from a root certificate provider.
surely an encryption key needs to be shared. If someone is eavesdropping on your connection, wouldn't they just be able to grab this key
No. The key is never transmitted. It is computed at both ends independently via a key-agreement algorithm.
What prevents a rogue server from faking a certificate signed by a root certificate provider?
The certificate is sent along with its digital signature which is made with the private key, and verified by the peer via the certificate's own public key. The server would need the private key of the server it is spoofing.
When using protocols such as Diffie-Hellman key exchange, the two parties to a communication each generate a random number, transform it in some way, and send the transformed version to the other party. The transformation is such that combining the first number with the transformed version of the second will yield the same result as combining the second number with the transformed version of the first. An adversary who only had the transformed numbers, however, would have no way of finding the un-transformed version of either, nor a way of computing what the result would be if the (unavailable) untransformed version of one number were combined with the (available) transformed version of the other.
Diffie-Hellman key exchange by itself would be sufficient to protect against all forms of passive attack or historical attacks (meaning if an attacker hadn't taken steps to intercept a communication before it took place, it cannot later be compromised except by performing some calculations which could not, with anything resembling today's technology, be computed in any remotely feasible time). The problem with it is that it cannot very well protect against the situation where an attacker (e.g. Z) can intercept all communications between the participants (e.g. X and Y) and substitute his own. In that scenario, X would establish a connection with Z--thinking him to by Y--which nobody but he and Z could decode. Z would then--pretending to be X--establish a connection with Y.
If X and Y have any pre-existing means of sharing information with each other in such a way that they can decode it much faster than Z, even if it's not terribly secure, this may suffice to prevent the above-described man-in-the-middle attack. All that needs to happen is for X and Y to ask each other something about the key they're using. If Z can recognize that question and substitute its own answer, it would be able to continue the ruse. On the other hand, if the question were asked in such a way that a legitimate party would be able to respond much more quickly than an imposter, Z might be stumped. As an example, if a voice-phone application displayed for each participant information about the negotiated key, and one party asked the other "read off digits 12 to 18 of your key, doing your best impression of Elmer Fudd" (selecting, on the spot, the digits to read and the voice to use) a legitimate participant would be able to respond immediately, but an attacker would need time to produce a phony recording of the person speaking as indicated).
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.
I'm currently developing a system to transmit data between client and server, and was wondering what the strength of the encryption I planned to use was.
My thought was to have a private/public RSA key pair and hand out the public key to each client (leaving the private key solely on the server). Each client would then generate their own AES key and RSA encrypt it. They would then AES encrypt their data and send the encrypted data and encrypted AES key to the server. The server would then decrypt the AES key using the private key, and then decrypt the data using the AES key.
Are there any security flaws I am missing and/or is there a better way to do this?
This is almost exactly how SSL/TLS works (check out the handshake section). The only thing to make it stronger is to generate the AES key for each connection, rather than using the same key each time. You might also want to digitally sign messages that go back and forth to avoid man-in-the-middle and other spoofing attacks.
Generally speaking, creating a good cryptosystem is very difficult. When possible, you should always favor an existing (trusted) application to help out. In this case, you might consider sending your messages using HTTPS, rather than creating your own system.
You should give us more information about the language and platform you are using, so that we can give you specific recommendations about libraries that already exist and wich will handle the details for you. Using cryptographic primitives directly is not trivial and difficult to get exactly right, and with cryptography, you have to be "not exactly right" only once for your security to be broken.
To answer your question, it's generally a better idea to create a session secret (the AES key) through a Diffie-Hellman exchange, and each side use its private RSA key to sign its key-exchange data.
Otherwise, if the session secret is not established through a DH exchange, an adversary that gains access to the private RSA key (which has to be stored somewhere) could decrypt all traffic that was ever sent between the client and server.
If the secret is established through a DH exchange, then only the authentication part of the protocol would be exposed. Although an adversary in possession of the private RSA key would then not be able to read any previous communication, he still could either enter an authenticated dialog with the client/server or launch a man-in-the-middle attack (which may or may not be easily done, depending on the network).
One vulnerability would be if an attacker substituted their public key for the "real" public key. Then they would be able to intercept traffic as a "man-in-the-middle."
Protocols like S/MIME, PGP, and TLS use RSA encryption to transport keys just as you propose. However, the public keys they use are in certificates signed by trusted authorities.
The integrity of these trusted authorities must be carefully protected. For example, they might be burned into a tamper-proof hardware token, or a MAC might be computed over them using a password.
I'm not sure your approach will protect anything! You're going to keep the private key on the server and the public key will be distributed. If I get a hold of your public key, I'll be able to interact with your server at will. I think you should reverse the key ownership; each client will hold it's-own private key and the server will have a list of public keys (ala SSH). The server will have to add 'authorized' public keys and only to holders of the private keys will be able to connect.
Hope this helps.