Link to home
Start Free TrialLog in
Avatar of k heitz
k heitz

asked on

Distributing a private key

Dear Experts,
I've been given a task I am not very knowledgeable about and hope you can provide some insight.

User's OS: Windows (Win7 & Win8; both 32 and 64 bit)
I have an application (VB6) that runs locally on users' systems. There are approximately 30 users on different systems in different locations. The distribution of the app is highly controlled and protected.

The app sends XML strings directly to a Receiver's site using HTTPS.post.

The task is to embed a signature in the HTTPS header so the Receiver can verify the message came from our company (any one of the 30 users). The Receiver is not interested in using Public/Private keys and our transmission to them does not go thru a server at any point.

Using makecert, I've created a local X509 certificate with a private key and have completed the work to generate the SHA1 hash to create the signature.

Here is where I am stuck - because I am very new to certificates, I don't understand how to get that private key to the app users.

My thought was to distribute the .cer file with the app setup (the code looks for the certificate in a specific directory) - then also snail mail the .cer to the Receiver.

Will this work?
Doesn't the private key have to be the same on all systems (for the signature to be the same?)
Am I way off base?

Thank you
klheitz
Avatar of becraig
becraig
Flag of United States of America image

In order to give users the private key you will have to export to pfx you can do so with certutil:

Certutil.exe -p <Password> –exportpfx Thumbprintofcert c:\pfxfile.pfx

Once you have done the above you can simply script out the copy and install of the cert to the users store this can be bundled as a part of installing your app, so when the user runs your app you can point to the path with the pfx and do an install e.g :

certutil –f –p <password> –importpfx C:\pfxfile.pfx



Once you are installing
A flow such as above should work, since the private key will be exported to the pfx file.
Here's an overview of how the general process should work; compare to your current approach.

User generated image

1.

Alice wants to send a message to Bob and provide confidentiality, integrity, proof of origin and proof of receipt.

2.

To protect the secrecy of her message contents, she uses a symmetric cipher to encrypt it. For that she uses a symmetric key. This produces a ciphertext message.

3.

To protect the accuracy of the message, she uses a hashing algorithm that condenses the arbitrary-length message to a fixed-size message digest value.

4.

To prove the message actually came from her, Alice signs the message by encrypting the hash value with her private key. The sum of the message digest encrypted with Alice's private key results in a digital signature.

5.

This digital signature is then appended to the bottom of the symmetrically encrypted message. Now in order for Bob to read, prove the origin, and check the accuracy of the message, he must reverse all of the encryption done above.

6.

To read the message, Bob needs a copy of the symmetric key. Alice encrypts it using asymmetric encryption and encrypts the symmetric key with Bob's public key, producing a ciphertext key.

7.

Bob decrypts the ciphertext key with his private key to give him his copy of the symmetric key.

8.

Bob uses the symmetric key to decrypt the message with that key and read it.

9.

Bob decrypts Alice's digital signature using Alice's public key. Once the decryption process is complete, he is left with the message digest.

10.

But, he has yet to prove the integrity of the message or the proof of origin. He must prove the message digest value is correct. To do this, Bob must rehash the message that he has received and decrypted.

11.

If the message digest that he generates from the message matches the message digest that he decrypted from Alice's digital signature, then he has proof of integrity and proof of origin.

12.

To prove that he received the actual message Alice sent, Bob re-encrypts the message digest with his private key, which will result in his digital signature.

13.

Bob sends his digital signature back to Alice.

14.

Alice decrypts Bob's digital signature using his public key to produce the message digest.

15.

She compares the message digest she just received to the message digest she originally generated. If these two message digests match, then she has proven that her message was received by Bob (proof of receipt) in its correct format (proof of integrity).
Avatar of CubeOver
CubeOver

I would advise you to look at deploying a web enrolment service so that clients can request certificates, and enrol them once you approve their requests.
I.e. you shall need the following roles deployed and available on the Internet or other network where all your clients have access:

ADCS - Certificate Enrollment Web Service
ADCS - Certificate Enrollment Policy Web Service

Please read up on both - you can start right from the Add Role Services Wizard.
Once deployed, give URI of the Policy Service to your clients along with instructions how to set things up.
Each computer shall have it's own certificate, allowing you to revoke it in case of compromise.
==>Please design, deploy and test CRL web service before doing anything else, otherwise you shall have no means of stopping the compromised computers from connecting (short of shutting down the solution!) Make sure your CA works well with CRL service before issuing any certs.
==>Also make sure the template you use specifies non-exportable enrolment. This will stop users from exporting private keys from one PC into another.

Clients will need credentials in your domain, you could also use one shared user/password pair - one user may have many certs issued to him.
Make sure that your CA requires your approval for every request. even renewals.
Once you see new request incoming you could call the user/company to verify correct enrolment, and then approve. The rest is automatic, I mean renewal request coming your way every year or period configured.

This is a free, scalable solution.
The benefit is you do not email private keys - everything happens inside SSL tunnel.
Another benefit is users only configure it once, for lifetime of your solution.

.CER files do not contain private keys, .P7B do.
Avatar of k heitz

ASKER

Hi bcraig;

I've determined this approach will work for me. I have run into some questions however.

I've been able to export the thumbprint a .pfx.

My first attempts failed (not found); so I used certutil to -addstore MY <cer path>. After doing so, it was successful.

In the dos window however, right above 'success' it reported:
'cannot find the certificate and private key for decryption' (i've attached a screen shot)

In your instructions you said:
"Once you have done the above you can simply script out the copy and install of the cert to the users store this can be bundled as a part of installing your app,"

I'm unfortunately ignorant in this area. is it possible to clarify? I'm not sure what you mean by 'script out the copy' (the pfx yes?).
'and install the cert to the users store' -

Will I be able to include the .pfx in my build; and run the
certutil –f –p <password> –importpfx C:\pfxfile.pfx command at the end of the install (vs. when the app itself runs)

Also - I don't know how to install it in the user's store. If I import as above and run certutil -addstore MY imported.cer will that do it?

I'm sorry to be so green at this.

Thank you
klheitz





Once you are installing
A flow such as above should work, since the private key will be exported to the pfx file.
certutil-export.png
ASKER CERTIFIED SOLUTION
Avatar of becraig
becraig
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of k heitz

ASKER

Hi becraig;
This is all great stuff and I feel I'm 99.5% of the the way there! Thank you so much!

Here's my final (I hope) brick wall.

After exporting the .cer to a .pfx and importing the .pfx ... what is the path of the imported .cer file? I've searched my system and cannot find it.

I ask because my vb.net code is as follows:

 Public Function GetSignature(ByRef XMLString As String) As String
        ' The path to the certificate.
        Dim Certificate As String = "c:\[path]\[filename].cer"
       
        ' Load the certificate into an X509Certificate object.
        Dim cert As New System.Security.Cryptography.X509Certificates.X509Certificate2(Certificate)

Does that make sense?
Thank you again!
klheitz
Ok so the problem here is that when the pfx is imported it is imported into the certificate store.  At this stage of your code what are you attempting to do next ?

Are you attempting to validate the certificate once it's installed ?
Avatar of k heitz

ASKER

I'm attempting to use the certificate's private key to apply SHA1 hash & create a digital signature. Full routine below:

    Public Function GetSignature(ByRef XMLString As String) As String
        ' The path to the certificate.
        Dim Certificate As String = "c:\[path to cert]\[filename].cer"
        Dim ByteConverter As New ASCIIEncoding
        Dim strDataString As String = XMLString

        'create byte arrays to hold orig & sigstring
        Dim OrigData As Byte() = ByteConverter.GetBytes(strDataString)
        Dim signedData() As Byte

        ' Load the certificate into an X509Certificate object.
        Dim cert As New System.Security.Cryptography.X509Certificates.X509Certificate2(Certificate)

        ' Create a new instance of the RSACryptoServiceProvider class  
        ' and automatically create a new key-pair.
        Dim RSAalg As New RSACryptoServiceProvider

        ' Export the key information to an RSAParameters object.
        ' You must pass true to export the private key for signing.
        Dim Key As RSAParameters = RSAalg.ExportParameters(True)

        ' Hash and sign the data.
        signedData = HashAndSignBytes(OrigData, Key)


        Dim sigString = Convert.ToBase64String(signedData)


        ' Verify the data and display the result to the  
        ' console.
        If VerifySignedHash(OrigData, signedData, Key) Then
            'MessageBox.Show("The data was verified.", "Verification", MessageBoxButtons.OK)
            ' Console.WriteLine("The data was verified.")
            GetSignature = sigString
        Else
            GetSignature = "The data does not match the signature."
            'Console.WriteLine("The data does not match the signature.")
        End If

        ' Display the value to the console.
        'Console.WriteLine(sigString)
        'GetSignature = sigString
    End Function
Avatar of k heitz

ASKER

I've requested that this question be closed as follows:

Accepted answer: 0 points for klheitz's comment #a39884586

for the following reason:

Very helpful - and patient! beCraig helped clarify my misunderstanding and offered excellent suggestions.
Avatar of k heitz

ASKER

(i might have done this wrong before - i think I accepted my own note as the solution and I didn't mean to)
beCraig's solution worked great. Thank you very much!