Persits Software, Inc. Web Site
Main Menu:  Home |  News |  Manual |  Tasks |  Object Reference |  Crypto 101 |  FAQ |  Download & Buy |  Clients |  Live Demo |  Contact
 Navigator:  Home |  Tasks |  Generate PKCS#7 Signatures and Envelopes
Use AspEncrypt as a Client-side ActiveX Control
  Generate PKCS#7 Signatures and Envelopes
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.
  What is PKCS#7
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.

  Encrypting & Decrypting Text Directly with Certificates

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)
%>

  Decrypting with Email Client

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
%>

  Generating Detached PKCS#7 Signatures

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")

  Signature Verification

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.

Use AspEncrypt as a Client-side ActiveX Control

Search this Site
  This site is owned and maintained by Persits Software, Inc. Copyright © 2000 - 2010. All Rights Reserved.