|
Starting with version 2.0, AspEncrypt is capable of generating
detached digital signatures and envelopes (encrypted messages)
in the PKCS#7 format. You can now encrypt and sign data directly
with a digital certificate in one easy step.
Public-Key Cryptography Standards (PKCS) are RSA Data Security, Inc.'s
series of de-facto standard formats for public-key cryptography.
Among all the PKCS standards, PKCS#7 is probably the most
widely used one. It describes a general syntax for data
that may have cryptography applied to it, such as digital signatures
and digital envelopes.
The S/MIME secure mail standard
uses PKCS#7 for its digitally signed and encrypted messages.
Certificate requests and certificate store (.spc) files
also normally use the PKCS#7 format. Every PKCS#7
blob usually encapsulates some content (such as an encrypted
message or signed hash value) and one or more certificates
used to encrypt or sign this content.
AspEncrypt (Version 2.0 and above) provides support for
the PKCS#7 format via the CryptoMessage
object.
The CryptoMessage object enables you to encrypt text information
directly with a certificate's public key in one easy step.
The resultant PKCS#7 encrypted message (also known as "envelope")
can only be decrypted with a private key context
associated with this certificate. Decryption can take place
on the client's machine using the XEncrypt ActiveX control,
or on the server.
PKCS#7 envelopes also
allow you to encrypt data with multiple certificates at the same time.
Any one of the corresponding private keys is sufficient
to decrypt the message.
The code sample http://localhost/aspencrypt/pkcs7/encrypt_cert.asp
demonstrates how to use the CryptoMessage object to
encrypt a text string with a certificate. For this code sample to work,
you must export your personal certificate to a .cer file
and place it on the server.
<%
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContextEx( "Microsoft Enhanced Cryptographic Provider v1.0", "mycontainer", True)
Set Msg = Context.CreateMessage(True) ' use 3DES
' Obtain encryption certificate
Set Cert = CM.ImportCertFromFile("d:\mycert.cer")
Msg.AddRecipientCert Cert
Encrypted = Msg.EncryptText("my secret phrase")
%>
|
You may have noticed that this snippet is very similar to the
encrypted mail code sample from the Secure Mail
task. The optional Boolean argument to Context.CreateMessage
specifies whether 168-bit TripleDES encryption is to be used (if set to True).
Otherwise, 40-bit RC2 encryption will be used.
The Msg.AddRecipientCert method can be called multiple
times if there are multiple certificates to be used for encryption.
The method Msg.EncryptText performs encryption on the specified text string and returns
a PKCS#7 envelope which may look similar to the following:
MIIBjwYJKoZIhvcNAQcDoIIBgDCCAXwCAQAxggE4MIIBNAIBADCBnDCBlDELMAkGA1UEBhMCWkEx
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRo
YXd0ZTEdMBsGA1UECxMUQ2VydGlmaWNhdGUgU2VydmljZXMxKDAmBgNVBAMTH1BlcnNvbmFsIEZy
ZWVtYWlsIFJTQSAxOTk5LjkuMTYCAwKjATANBgkqhkiG9w0BAQEFAASBgJ62XNAmDkEk2Y4fwNjF
mGosMWR4lbpWLq+zw5DWrEO5L7fEEyqZDft7u23q7HhlPeGDV+UnsiTot131DZEXNB0/Czzy+pDx
fz2tWvY8RkNH4Bz6Jguv2nI36r1YcroaeCmtD0nuycXLcglFxV1hwtT4NX2lPDxOltzRnGBMuE78
MDsGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIYbPCH5G5SISAGOe+XgeABfKCjzU3AosQV2JPWXxi
1kYqNc==
Even a short string turns into a relatively large encrypted blob
because a PKCS#7 envelope also contains the certificate used for encryption.
The corresponding decryption code is even simpler than encryption code.
To decrypt a PKCS#7 envelope, you must call
Msg.DecryptText and pass it, besides the blob, the name of the
private key container for the encryption certificate. This name
can be obtained via the expression Cert.PrivateKeyContext.ContainerName.
If no container name is specified, AspEncrypt will try
all certificates in the MY store until a match is found.
The following code snippet is to be executed on the user's machine
using the XEncrypt ActiveX control:
...
<SCRIPT LANGUAGE="VBScript">
Sub Decrypt
Set Context = XEncrypt.OpenContextEx("Microsoft Enhanced Cryptographic Provider v1.0", "mycontainer", False)
Set Msg = Context.CreateMessage(True) ' use 3DES
MsgBox Msg.DecryptText(document.myForm.txtEncr.value, "")
End Sub
</SCRIPT>
</HEAD>
<BODY>
<OBJECT
classid="CLSID:F9463571-87CB-4A90-A1AC-2284B7F5AF4E"
codeBase="aspencrypt.dll"
id="XEncrypt">
</OBJECT>
<FORM NAME="myForm">
<TEXTAREA NAME="txtEncr" ROWS="10" COLS="80"></TEXTAREA><BR>
<INPUT TYPE="BUTTON" OnClick="Decrypt" VALUE="Decrypt">
</FORM>
...
|
If decryption is to take place on the server, the encryption certificate's
private key context is be retrieved as follows:
<%
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Store = CM.OpenStore("MY", True)
Set Cert = Store.Certificates("<serial number>")
Set Context = CM.OpenContext("mycontainer", True)
Set Msg = Context.CreateMessage(True)
Response.Write Msg.DecryptText(txtEnvelope, Cert.PrivateKeyContext.ContainerName)
%>
|
Using XEncrypt as described above is not the only way
to decrypt a PKCS#7 envelope on the user's machine. An alternative
method is to generate an email message with the PKCS#7 blob as the message body.
An S/MIME-enabled email client such as Microsoft Outlook, Outlook Express
or Netscape Messenger with a digital certificate installed will
be able to decrypt the envelope and display its content to the user.
For this scheme to work, certain MIME headers have to be added
to the email message, and the CR/LF characters must
be prepended to the text string before it can be operated on
by Msg.EncryptText.
We will use AspEmail, Persits Software Inc.'s free mail component,
to demonstrate this technique. The code snippet below can
also be found in the file
http://localhost/aspencrypt/pkcs7/encrypt_mail.asp.
<%
Message = "This is my secret message!!!"
' Prepend message with a CR/LF characters to comply with MIME format
Message = chr(13) & chr(10) & Message
' Encrypt message with a certificate
Set CM = Server.CreateObject("Persits.CryptoManager")
Set Context = CM.OpenContext("mycontainer", True)
Set Msg = Context.CreateMessage
' open encryption certificate
Set Cert = CM.ImportCertFromFile("d:\mycert.cer")
Msg.AddRecipientCert Cert
' Create PKCS#7 envelope
Encrypted = Msg.EncryptText(Message)
' Send this PKCS#7 envelope by email to certificate's owner
Set Mail = Server.CreateObject("Persits.MailSender")
' Set your own host address here
Mail.Host = "mail.atlantech.net"
Mail.From = "me@mycompany.com"
Mail.Subject = "Sample encrypted message"
' Add custom headers
Mail.AddCustomHeader "Content-Type: application/x-pkcs7-mime;name=""smime.p7m"""
Mail.AddCustomHeader "Content-Transfer-Encoding: Base64"
Mail.AddCustomHeader "Content-Disposition: attachment;filename=""smime.p7m"""
' set the message body to the PKCS#7 envelope
Mail.Body = Encrypted
' set this to the certificate's owner's email address
Mail.AddAddress "peter@persits.com"
' Send
Mail.Send
%>
|
The CryptoMessage object can also be used to generate detached
PKCS#7 digital signatures using a user certificate's private key.
To let a user pick a certificate for signing,
you can follow the same procedure as in the previous task.
The only difference is that instead of using Hash.Sign
to generate a signature, you should use Msg.SignText, as follows:
' Obtain signer certificate into Cert
...
Set Context = XEncrypt.OpenContext("containername", False)
Set Msg = Context.CreateMessage(True)
Msg.SetSignerCert Cert
Signature = Msg.SignText("text to sign")
|
The CryptoMessage object is also capable of generating PKCS#7 signatures from
arbitrary files via the method Msg.SignFile. This method
is identical to SignText except that it expects a file path
as an argument:
Signature = Msg.SignFile("c:\path\myfile.ext")
The CryptoManager object provides the method VerifySignature
which verifies a detached PKCS#7 signature against
a given hash value and a public key conatained in a certificate.
The following code verifies a signature generated by the previous
sample:
<%
...
Set Cert = CM.ImportCertFromFile("c:\mycert.cer")
Set Msg = Context.CreateMessage(True)
Set Hash = Context.CreateHash 'SHA by default
Hash.AddText "text to sign"
IsValid = Msg.VerifySignature(Signature, Hash, Cert)
%>
|
In this code sample, we create an empty hash object
and compute the hash value of a text string we had signed.
We also obtain the public key portion of a signer certificate.
The PKCS#7 signature, hash value and certificate are then passed
to the VerifySignature method which returns True if the signature
is verified, or False otherwise.
Note that the hashing algorithm used to verify a signature
must match that used to create it. CryptoMessage always
uses the SHA algorithm, which is also the default
option for the CreateHash method. If a signature
was generated by an application other than AspEncrypt, you must find out
which algorithm was used (SHA, MD4, MD5), and create the hash object accordingly.
|
|
|
|
|