Articles
Using Certificates in
Delphi Applications
by Henrick Hellström, StreamSec
This document is intended to be used as an introduction
to the use of X.509 Certificates for Authentication in Delphi programming.
The focus is towards SSL/TLS enabled communication applications and the
components in the StreamSec®Tools library.
What is a Certificate?
What problems do Certificates solve?
Using Certificates in Delphi Applications
Using Certificates with StreamSec Tools
CertMgr
TSimpleTLSInternalServer
Typical setup
Using Certificates for Authorization
Appendix
Public Key Cryptography.
RSA
Diffie-Hellman.
DSA
A X.509 Certificates consists of four types of
information:
1.
A Public Key. This is really the only information contained in the
certificate you need in order to perform cryptographic operations, such as
SSL/TLS handshakes, digital signature verification etc. The reason a
certificate contains more information is that if you only have a public key
coming from nowhere there is no way for you to tell who has the
corresponding Private Key in the key pair. Consequently, the certificate
will also contain:
2.
A definite description of the entity in control over the private key
corresponding to (1), including a Subject name, information about
what kind of application the subject is using the private key with, the
validity period of the certificate, a serial number, etc.
However, what guarantee do you have that the information identifying the
subject is true? Anyone could generate a RSA key pair, and, say,
claim to be Microsoft. What you need is for someone you trust to certify
that the person in control of the public key is really the entity described
by the subject name. That is why the certificate also includes:
3.
A digital signature of the information in the certificate,
including:
4.
A definite description of the entity that signed the certificate.
This entity is commonly referred to as the Issuer or the Certificate
Authority (CA).
The Issuer Certificate will also contain Subject and
Issuer information plus a signature field. The Issuer information in the
Issuer Certificate might either identify yet another CA, or point back to
itself. In the former case the Certificate Issuer is an Intermediary
Certificate Authority; in the latter case a Root Certificate Authority.
Certificates are used as part of a Public Key
Infrastructure (PKI), and the purpose of a PKI is, roughly, to reduce,
firstly, the amount of cryptographic material each certificate user in the
system has to manage, and, secondly, the amount of information that has to
be exchanged initially through physically secure channels, in order for the
entire system to be secure.
One way to conceptualize the benefits of using a PKI is
to look at the alternatives:
Alt
1. All
information is transmitted through physically secure channels. Example: No
information is exchanged except between rigorously identified individuals
who meet in person in window-less rooms immediately after a bug sweep they
conducted themselves.
Alt
2.
Symmetric keys are transmitted through physically secure channels, and the
bulk of information is transmitted through insecure channels protected by
the symmetric keys. Security systems of this kind might be more practical
than Alt 1, but they are still impractical for most applications. Firstly,
they still require that each pair of peers have access to a physically
secure channel at least once. Secondly, the potential total number of
symmetric keys that have to be maintained throughout the system is
proportional to the square of the number of peers in the systems, e.g. 9900
keys in a system with 100 peers, 999000 keys in a system with 1000 peers
etc. Each of these keys has to be put in a protected storage to guarantee
both confidentiality and authenticity.
Alt
3.
There are two common ways to reduce the number of keys that have to be
managed with Alt 2. The first involves a trusted key server that generates
symmetric keys on demand from any pair of identified peers. Each peer will
only have to maintain keys that will allow protected communication with the
key server. This solution is fairly practical and a variation of it was used
in the Kerberos protocol. The greatest problem has more to do with the
security than the practicability of such systems, since the entity operating
the key server has to be implicitly trusted with all information that is
transferred throughout the system – since the key server has all keys, it
will theoretically also have read/write access to all communication.
Alt
4. The
second way to reduce the number of keys that have to be managed with Alt 2
is to use asymmetric key pairs instead of symmetric keys. Without a trusted
server or a certificate based PKI, such a system would still require that
each pair of peers exchange public keys through a physically secure channel.
This is how the initial key exchange is handled e.g. by the PGP community,
together with a so-called “web of trust”. The only material benefit with
this alternative compared to Alt 2 is that each peer only has to keep his or
her own private key confidential. The public keys belonging to other peers
just have to be stored in a manner that guarantees their authenticity.
Alt
5. Add
a trusted server for asymmetric key management and distribution, and you
will end up with something similar to the Lightweight Directory Access
Protocol (LDAP). Using read-only LDAP over a secured tunnel, e.g. SSL/TLS,
IPSec or SSH, might be a both secure and efficient solution provided that
the peers exchange public keys securely with the entity operating the LDAP
server. The security requirements would be that each peer keeps his or her
own private key confidential, the public key of the LDAP server authentic,
and that the LDAP server is able to guarantee the authenticity of the public
key of each peer at any time.
The use of Certificate Authorities reduces the need for
a central trusted server. Instead of obtaining the public key from the
central server, each peer would obtain certificates directly from the owner,
and authenticate them simply by checking the signatures. Each public key
would still have to be physically authenticated by a central entity, in this
case the CA, but it would be possible for each pair of peers to obtain a
reasonable degree of security with less network traffic.
There would still have to be some mechanism for
validating certificate since they might be revoked. Such mechanisms include
central Online Certificate Status Protocol (OCSP) servers or Simple
Certificate Validation Protocol (SCVP) servers. If revocations are rare
and/or the number of peers in the system is not too large, an alternative
would be for the CA to distribute the most recent Certificate Revocation
List (CRL) directly to each peer in case of a revocation.
With StreamSec Tools it is easy to roll your own CA
operation and issue certificates to each peer of your system. StreamSec
Tools provides tools for doing this at both design time and run time.
CertMgr
The CertMgr project demonstrates basic CA
functionality. It maintains four certificates stores, each of which is
listed on a tab in the main form and saved to a separate file in the path of
CertMgr.exe.
- The Personal tab lists the certificates created with
this instance of CertMgr. This store is saved to the User.scl file and the
private keys corresponding to these certificates are saved to the User.pkr
file.
- The Issued tab lists the certificates created from
certificate requests and signed with a certificate in the personal store.
Typically, the private key corresponding to each of these certificates is
stored elsewhere.
- The Root tab and the Collected tab list all other
certificates. Each of these certificates has been imported with CertMgr,
and has typically neither been signed nor created using this instance of
CertMgr. CA certificates should be imported into the Root store, although
this is not a requirement. The Root store should only contain certificates
that are explicitly trusted, since any certificate in any other store will
be implicitly trusted through CA chaining if the issuer certificate is
present in the Root store.
The TSimpleTLSInternalServer component provides design
time support for certificate creation. It maintains three certificate
stores, each of which is streamed to the dfm resource if it is loaded at
design time, correspond to its own set of properties and has its own
purpose:
- The MyCerts store corresponds to the Personal tab in
CertMgr. Typically, this is where server certificates should end up in a
server application, and where client certificates should end up in a
client application. It must only contain certificates with the
corresponding private key in the private key ring maintained by the same
TSimpleTLSInternalServer instance. (Please note that there are ways to
circumvent this restriction, and that doing so inadvertently might result
in unexpected design time and run time behavior.)
- The RootCerts store corresponds to the Root tab in
the CertMgr. This store should contain all certificates the component
needs to properly perform CA chaining on any certificate that should be
implicitly trusted. This store must be loaded before the MyCerts store and
must contain all issuer certificates for the certificates in the MyCerts
store, and also all issuer certificates for any certificate that the
component is expected to trust implicitly, such as the certificates of
remote TLS peers.
- The TrustedCerts store contains any other
certificate the component is expected to trust explicitly. Typically, this
is where commercial client certificates belonging to authorized users end
up, since adding e.g. a VeriSign root certificate to the RootCerts store
would seriously compromise the security of many applications.
A typical system setup with an in-house server might
look like this:
1.
Generate a root certificate with the CertMgr application. (Make sure
the Validity NotBefore date is not set after the present time.) Export it to
a .cer file. The root certificate will be saved to the file User.scl and the
matching private key to User.pkr when CertMgr is closed.
2.
Drop a TSimpleTLSInternalServer component on a module in your server
application. Right-click on the component to import the root certificate and
then create Server Certificate Request. Export it to a .p10 file. The
matching private key is stored inside the component and will be password
encrypted and streamed to the .dfm file when the module is saved – but don’t
try this yet: It is not recommended to save a module with a
TSimpleTLSInternalServer component that doesn’t hold any personal
certificates. So far only a private key and a certificate request have been
created.
3.
Import the .p10 file with the New Certificate wizard in CertMgr. Sign
it and export the certificate to a file. Make sure the Validity NotBefore
date is not set after the present time. If there is more than one CA
certificate on the Personal tab of CertMgr you must make sure that you
select the same certificate as issuer certificate as the one you imported
with the TSimpleTLSInternalServer component at 2.
4.
Import the certificate with the TSimpleTLSInternalServer component by
selecting Open File and the Personal Certificate filter. The certificate
should now show up as the single certificate in the MyCertList collection
after clicking Add New in the collection editor.
5.
Attach the component to e.g. a DxSock, Indy, kbmMW or RemObjects
server component. Save the project. The server private key and the two
certificates will now be stored in the module resource.
To create a client application:
6.
If there isn’t one already, create a password list for all client
users. These passwords, or rather Registration Tokens, will be used for
Client Certificate Request authentication.
7.
Drop a TSimpleTLSInternalServer component on a module in your client
application. Set the ClientOrServer property to cosClient. Attach it to e.g.
a Indy, kbmMW or RemObjects client component. Right-click to import the root
certificate. Note that it is recommended to load the User.scl file rather
than just the root certificate .cer file.
8.
Add a method to the client application for Client Certificate Request
generation. With kbmMW, this method might look like this:
var
MS:
TMemoryStream;
CertReq: TCertificationRequest;
Cert: TCertificate;
vCR, vCer: Variant;
Status: TCertStatusCode;
begin
MS :=
TMemoryStream.Create;
try
{*** Create Client Certificate ***}
if not
TLSClient.NewClientCertReqDlg(MS) then
kbmMWRaiseException('Failure generating Certificate
Request');
TLSClient.SavePrivateKeyRing('Client.pkr');
MS.Position :=
0;
CertReq :=
TCertificationRequest.Create(nil,nil);
try
CertReq.LoadFromStream(MS);
vCR := kbmMWObject2Variant(CertReq);
vCer := CaClient.Request('CA_SERVICE','1.0','NEWCERT',[vCR]);
Cert := kbmMWVariant2Object(vCer) as
TCertificate;
try
TLSClient.AddCertificate(Cert.Data,False,Status);
if
Status <> crcOK then
kbmMWRaiseException('Illegal certificate returned
from host');
Cert.SaveToFile('Client.cer');
finally
Cert.Free;
end;
finally
CertReq.Free;
end;
finally
MS.Free;
end;
end;
9.
Add a method to the server application that will handle Client
Certificate Requests by verifying the signature, the registration token and
all of the certificate fields, and issue a certificate if the request passes
all tests.
Client authentication is one of the security services
optionally offered by SSL/TLS. With the TSimpleTLSInternalServer component
this service is on by default. Set the Options.RequireClientCertificate
property to False to disable it. When enabled, the server will only treat
clients with valid certificates issued by the in-house certificate authority
as authorized to use the application services offered by the server.
This functionality can be extended. For example, it is
recommended to use at least two different intermediary CA certificates in a
large or medium sized Public Key Infrastructure. The first CA certificate is
used only for issuing certificates used for certificate issuing services,
such as Registration Authority (RA) client and server certificates. The
second CA certificate is used for issuing all other certificates in the
system. Each TSimpleTLSInternalServer component should have only one of
these certificates in its root certificate store, depending on if the
component provides SSL/TLS for CA/RA services or application services.
Public Key Cryptography is a term that is used to
describe a wide range of security service. The defining criterion for Public
Key Cryptography is that it involves the use of Asymmetric Key Pairs. Such a
key pair consists of one Private Key and one Public Key. The entity that
generates the key pair keeps the Private Key and discloses the Public Key.
RSA can be used for Public Key Encryption and as a
Digital Signature scheme.
When used for Public Key Encryption, any entity in
possession of the Public Key uses it to encrypt small pieces of information,
and sends the cipher text to the entity in possession of the Private Key who
is the only one able to the decrypt that cipher text.
RSA Digital Signatures work in a similar fashion, but
with reversed roles. In this case the entity in possession of the Private
Key uses it to encrypt a small piece of information (usually a Message
Digest of a larger piece of information), and sends the “cipher text”, which
in this case is referred to as a Digital Signature, to any entity in
possession of the corresponding Public Key. The latter entity uses the
Public Key to decrypt the Digital Signature and verifies that the result
matches the signed information.
RSA Private Key
1.A large
prime p.
2.Another
large prime q, roughly the same size as p.
3.A
private exponent d
RSA Public Key
1.A
public modulus n, with n = p * q.
2.A
public exponent e, with e * d = 1 (mod (p-1)*(q-1)).
RSA Operation
Public Key Encryption / Decryption: C =
Pe (mod n)
Private Key Decryption / Encryption: P = Cd
(mod n)
The plain text P should be encoded prior to encryption
and decoded after the decryption. Common encoding functions are specified in
PKCS#1.
Diffie-Hellman is used for Key Agreement. A Key
Agreement involves two entities each with it’s own key pair. Each of these
two entities knows of the Public Key belonging to the other entities, and by
performing an operation on their own Private Key and the Public Key in
possession of the other entity, they both arrive at the same result.
Diffie-Hellman Private Key
1.A large
prime q (normally 160 bits).
2.A large
prime p (normally 1024 bits) such that q divides (p-1).
3.An
integer g such that gq = 1 (mod p).
4.A
private exponent x, with 1 < x < q.
The elements (1), (2) and (3) are system parameters and
are usually shared by several key pairs.
Diffie-Hellman Public Key
1.The
system parameters q, p and g from the private key.
2.A large
integer y, such that y = gx (mod p)
Diffie-Hellman Operation
Alice: S = y_bx_a (mod p),
Bob: S = y_ax_b (mod p),
Where (x_a,y_a) is the key pair generated by Alice and
(x_b,y_b) is the key pair generated by Bob. Both key pairs must share the
same system parameters (q,p,g).
DSA is used for Digital Signatures. DSA uses the same
kind of keys and system parameters as Diffie-Hellman, but a more complex
operation when generating and verifying signatures.
|