Which is the private key? - ssl

I bought a ssl certificate for my site, but I do not know which one is the private key.
Here are the available files:
CACertificate-INTERMEDIATE-1.cer
CACertificate-ROOT-2.cer
PKCS7.p7b
ServerCertificate.cer

Meta: this is not a programming or development Q and will likely be voted offtopic.
None of them.
The (normal) sequence is:
you generate a key pair, or a private key which implies the matching public key, on your machine
you create a CSR (Certificate Signing Request) containing your public key, which is signed using your private key. With some software steps 1 and 2 are combined.
you send or submit the CSR to a CA, and also provide proof of identity and if applicable payment; the details of this step can vary depending on the CA you use, the type of cert you request (especially the validation), and who or what you are
the CA validates your identity (and payment) and 'issues' a certificate for you
the CA gives you your cert, plus the related CA certs needed to form a trust chain; this is often one intermediate plus a root (as in your Q) but other combinations are possible.
You are looking only at step 5. You need to look back at step 1 (and possibly 2).

Related

How to create RsaSecurityKey.KeyId with IdentityServer4

I'm using IdentiyServer4 to generate tokens, I'm using the AddDeveloperSigningCredential() method to generate my RSA key with a KeyId.
But, in production, I'm using AddSigningCredential(CreateSigningCredential()), to generate a key like this :
private SigningCredentials CreateSigningCredential()
{
var signinkey = new RsaSecurityKey(RSA.Create());
signinkey.KeyId = "abcdefghijklmnopqrstuvwxyz";//How to generate KeyId ??
var credentials = new SigningCredentials(signinkey,
SecurityAlgorithms.RsaSha256);
return credentials;
}
How can I generate a KeyId? Can I set it to any arbitrary value?
You don't need to set the keyId and also creating the RSA key youself in code, sounds like bad practice. Then you can just as well use the AddDeveloperSigningCredential method.
You can actually look at the source for that method here to see how they do it in code:
https://github.com/DuendeSoftware/IdentityServer/blob/main/src/IdentityServer/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs
But, in production you should generate the key externally and pass it in to IdentityServer, so the key is the same across redeployment/restarts. Otherwise previously issued tokens will not be valid anymore.
You can for example store the key in Azure Key Vault, or using some other configuration/secret system. Or in a database or as a file somewhere.
If you want to create one manually, using OpenSSL, then you can write
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -aes256 -out rsa-private-key.pem

certificate signing request: Does it contain public key or private key?

I am trying to demystify how CSR is generated, and role of the public and private key.
Server1:
Generate a public and private key
Now, I want CSR and for that, I will go to a CA for signing.
For creating a CSR request, is it based on server's public key or private key?
I referred to this SO question; in there, it says the server (which is requesting for CSR) itself signs CSR by its private key, before sending it to CA.
I am bit confused, have the following questions:
The end product (the signed certificate by CA): Does it contain server's private key or public key? I understand that the end product should contain the public key of the server requesting CSR.
While initiating a CSR request, why a server needs to sign a CSR by its private key? Is it correct?
Is server's public key part of CSR?
Eventually, does CA generate a certificate from CSR and how it derives the public key of the server from CSR?
The end product (the signed certificate by CA): Does it contain server's private key or public key?
The certificate is a public document. It therefore can only contain the public key. If it contained the private key, then that key wouldn't be private any more.
While initiating a CSR request, why a server needs to sign a CSR by its private key? Is it correct?
Yes, it is generally correct. This concept is called Proof of Possession (PoPo) and it used to prove to the CA that you (or the server in this case) have the private key corresponding to the public key which will be signed by the CA (or at least had it at the time just before the CA signed your certificate). If the CA didn't insist on PoPo then you could repudiate any signed future message as follows:
You have your public key signed by the CA to create your certificate. At the time, you sign your request with your private key as you should. Everything is good.
I come along and copy your public key from your certificate. I now present that to the CA as a CSR but without PoPo. The CA signs it and sends me a certificate, which now contains my name and your public key.
At some point, you send a digitally signed (with your private key) message to a third party, say your bank, asking them to donate $1000 to Stack Overflow.
You later decide that the $1000 would be better spent on a vacation, so you dispute the signed message to your bank.
The bank says But you digitally signed the message to authenticate it!!
As you know the CA signs certificates without PoPo, you simply have to say that I must have sent the message instead, using your private key which I've now destroyed in an attempt to hide the evidence.
The bank cannot prove that (6) isn't true as they didn't check I had possession of the private key corresponding to the public key in my request, and therefore your statement of it wasn't me cannot be rejected - the bank has to reimburse you.
If the bank insisted on PoPo when I submitted your public key to the CA, my request would have failed and you could not repudiate your message later. But once a CA signs a request without PoPo - all bets are off for non-repudiation.
Eventually, does CA generate a certificate from CSR and how it derives the public key of the server from CSR?
There is no derivation to do - your server's public key is in the request in a construct called a CertificateRequestInfo.
This CertificateRequestInfo contains your (or server's) name and the public key. It can also contain other elements such as requested extensions. The CA takes whatever information it requires from this CertificateRequestInfo (only the public key is mandatory) and uses the info to generate a construct called a tbsCertificate (the 'tbs' stands for To Be Signed). This construct contains your name, your public key and whatever extensions the CA deems fit. It then signs this tbsCertificate to create your certificate.

Format Public key

I am working on signing certificate with HSM, and I need to format the CA public key and output it. I read the EMV Book and the format as follows:
Field Name Length Description Format
Registered
Application Provider 5 Identifies the payment system to b
Identifier (RID) which the Certification Authority
Public Key is associated
Certification
Authority Public Key 1 Identifies the Certification
Index Authority Public Key in b
conjunction with the RID
Certification
Authority Hash 1 Identifies the hash algorithm used b
Algorithm Indicator to produce the Hash Result in the
digital signature scheme
Certification
Authority Public Key 1 Identifies the digital signature
Algorithm Indicator algorithm to be used with the b
Certification Authority Public Key
Certification
Authority Public Key Var. Value of the modulus part of the b
Modulus (max Certification Authority Public Key
248)
Certification
Authority Public Key 1 or 3 Value of the exponent part of the b
Exponent Certification Authority Public Key,
equal to 3 or 216 + 1
Certification
Authority Public Key 20 A check value calculated on the b
Check Sum36 concatenation of all parts of the
Certification Authority Public Key
(RID, Certification Authority
Public Key Index, Certification
Authority Public Key Modulus,
Certification Authority Public Key
Exponent) using SHA-1
I am writing the code with Visual Basic.net.How can I format this in the code and output? I made a Class named PublicKey, and there has three functions, ExportPublicKey, FormatPublicKey and WritePublicKeyToFile.
Can anyone help? Thank you very much.
What ever you have given is the minimum required data to be available in the terminal to validate Issuer Public Key Certificate signed by CA Private Key. On the terminal you will have the CA Public key list which you will match with the data from the card(using RID and exponent from card), get the correct CA Pubic key and open the certificate. But your requirement "format the CA public key and output it" makes no sense to me.
The format of Issuer Public Key certificate will be as below.
On a HSM Racal 9000, the command to generate a certificate will be EW, however I have not used it ever.
Note : The above are based my understanding of your issue. If you think my understanding meets your requirement, go through the whole section which explains about Offline Data Authentication. It is very interesting. Otherwise gently ignore ;)

Verify user identity on my site, using SSL Certificates

I need to register companies on my site for an electronic procurement system. Up to now these were local companies I could meet physically and give credentials to, but now they can be companies based anywhere in the world.
The solution is to have an online registration process whereby they submit a third party certificate. So say Verisign says they are 'Company X' so I register them as Company X and issue them credentials.
How can I implement this on my site? Do I simply give them a field in the registration form where they upload their certificate file? Do I then manually check these certificates in my back office? How does one check this manually? Is there a way to automate this process?
Once they have an account, should I simply request the credentials I issue them with to log in, or can all future logins request the same certificate file? In these a particular format for certificates I can request or should I allow a number of common formats that different certificate vendors provide?
Thanks in advance.
Being able to provide a certificate does unfortunately not prove anything. A certificate is completely public, and anyone can get a hold of the SSL certificate for any website. The certificate contains a public key. Proving ownership of the corresponding private key is what's required.
This is possible to do, but it requires that your users are technical enough to know how to run scripts and/or OpenSSL terminal commands so that they can sign something with their private key. Having the users upload their private key is of course a big no-no, as it means you can now act as the user, and that would require an enormous amount of trust in you to discard the private key after you've verified it.
From a technical perspective, you can do the verification by creating some kind of challenge, for example a random string, and have the user encrypt this string with their private key. If you decrypt this string with the public key in the certificate, and get the original string back, then you know that they have possession of the corresponding private key.
Here's a self-contained Ruby script that demonstrates this, with comments indicating which part of it is run on your side, and which part is run on their side.
require "openssl"
## This happens on the client side. They generate a private key and a certificate.
## This particular certificate is not signed by a CA - it is assumed that a CA
## signature check is already done elsewhere on the user cert.
user_keypair = OpenSSL::PKey::RSA.new(2048)
user_cert = OpenSSL::X509::Certificate.new
user_cert.not_before = Time.now
user_cert.subject = OpenSSL::X509::Name.new([
["C", "NO"],
["ST", "Oslo"],
["L", "Oslo"],
["CN", "August Lilleaas"]
])
user_cert.issuer = user_cert.subject
user_cert.not_after = Time.now + 1000000000 # 40 or so years
user_cert.public_key = user_keypair.public_key
user_cert.sign(user_keypair, OpenSSL::Digest::SHA256.new)
File.open("/tmp/user-cert.crt", "w+") do |f|
f.write user_cert.to_pem
end
## This happens on your side - generate a random phrase, and agree on a digest algorithm
random_phrase = "A small brown fox"
digest = OpenSSL::Digest::SHA256.new
## The client signs (encrypts a cheksum) the random phrase
signature = user_keypair.sign(digest, random_phrase)
## On your side, verify the signature using the user's certificate.
your_user_cert = OpenSSL::X509::Certificate.new(File.new("/tmp/user-cert.crt"))
puts your_user_cert.public_key.verify(digest, signature, random_phrase + "altered")
# => falase
puts your_user_cert.public_key.verify(digest, signature, random_phrase)
# => true
## On your side - attempting to verify with another public key/keypair fails
malicious_keypair = OpenSSL::PKey::RSA.new(2048)
puts malicious_keypair.public_key.verify(digest, signature, random_phrase)
Note that this script does not take into account the CA verification step - you also obviously want to verify that the user's certificate is verified by a CA, such as Verisign that you mentioned, because anyone can issue a certificate and hold a private key for foo.com - it's the CA signature of the certificate that provides authenticity guarantees.

How to get a public OpenPGP key only knowing its fingerprint?

I have only an OpenPGP key's public fingerprint. I do not know the key ID or almost anything else.
How can I get the corresponding public key? Are there any online service to do this?
How the Fingerprint and Long and Short Key IDs are Related
Each OpenPGP key has a fingerprint attached, calculated mainly from its public key packet which also contains the creation time. The calculation is defined in RFC 4880, OpenPGP, 12.2. Key IDs and Fingerprints.
There are short and long key IDs, which resemble the lower 32 respective 64 bits of the fingerprint. For example, looking at the IDs of my OpenPGP key:
fingerprint: 0D69 E11F 12BD BA07 7B37 26AB 4E1F 799A A4FF 2279
long id: 4E1F 799A A4FF 2279
short id: A4FF 2279
Fingerprints and key IDs are used, as sharing and comparing a whole key with usually 1024 to 8096 bits (adding some more for headers like the creation date) is very impractical.
Receiving Keys from Key Servers
There is a bunch of key servers used to distribute keys -- they communicate with each other, choose any of them. GnuPG's option --keyserver hkp://pool.sks-keyservers.net (often set in it's configuration file ~/.gnupg/gpg.conf for Linux/UNIX systems, another path on Windows) uses a pool that will chose a random one each time you use it.
You can use any of those short and long IDs respective the full fingerprint to fetch the key using the --recv-keys command in GnuPG, while the fingerprint is the most specific (and chances for collisions with short key IDs are highest).
If no colliding keys exist, following statements would fetch the same key:
gpg --recv-keys 0D69E11F12BDBA077B3726AB4E1F799AA4FF2279
gpg --recv-keys 4E1F799AA4FF2279
gpg --recv-keys A4FF2279
If you want to query the key servers from your browser, make sure to search for the fingerprint, long or short key ID prefixed by 0x to indicate a search for key IDs (the GnuPG command line interface will do this for you automatically).
Yes, there are servers for this. You can get key like this:
gpg --recv-keys <KEY_ID>
Update: see how KEY_ID interconnected with fingerprint:
Fingerprint: EC2392F2EDE74488680DA3CF5F2B4756ED873D23
Long Key ID: 5F2B4756ED873D23
Short Key ID: ED873D23