Creating Digitally Signed Content
Providing reliable content to end users is an important part of app development, especially considering apps that have paid features or other elements that depend on trusted information. This article provides detailed instructions for creating secure, digitally signed content and testing its validity.
A Real World Example
Mary, app developer for Contrary, Inc., has been told to create an app that will run as a demo until the end user pays for a license. Once a license is obtained, and installed, the app should run without any restrictions. Mary decides the best way to know whether or not a license is valid is to digitally sign it, transfer it to the end user's machine, and use her app to verify that the signed content is valid. If it is, the app will run unrestricted. If the license is not valid, the app will continue to run as a demo.
Mary begins by creating her own digital certificate using various Microsoft digital certificate utilities. She then uses the Window-Eyes app WESign, along with her digital certificate, to create an install-able package of signed content that contains the end user's Window-Eyes serial number, tying the license to that specific copy of Window-Eyes. Mary then provides the content package to the end user, and the end user installs the package on the machine with the matching Window-Eyes serial number. The next time Mary's app runs, it will locate the signed content, and verify that the content's signature matches the signature that Mary originally used to sign the content. Once the content is verified, Mary's app will run fully licensed rather than as a demo, and the end user will enjoy the new features that they paid for.
Your Own Digital Certificate
Digital signatures are often used to offer assurance that content came from a known source, and that it has not been tampered with. A digital signature can be verified by a certificate authority or can be self-signed.
For the purposes of signing content specifically for app use, having a digital signature verified by a CA is unnecessary. After all, the communication path will be between the developer and the app, and will not involve any other party.
All of the tools necessary to create a self-signed certificate are available through the Microsoft Windows SDK. There are three specific, command line utilities that can be used to create a Personal Information Exchange (PFX) Certificate:
Begin by useing makecert to create a standard X.509 certificate (a private key file (PVK) will also be created):
makecert -r -pe -n "CN=My Name" -sv mycert.pvk mycert.cer
Replace My Name with your own subject name, or a name you want to associate with your digital certificate. When prompted, enter a unique password for the certificate. You will need to retain this password for future use.
After your certificate and private key files have been created, you will need to create a Software Publisher's Certificate (SPC) using the cert2spc utility:
cert2spc mycert.cer mycert.spc
The SPC file is the public key for your digital certificate. You then need to combine the private key with the public key to create a Personal Information Exchange (PFX) file:
pvk2pfx -pvk mycert.pvk -pi "password" -spc mycert.cer -pfx mycert.pfx -po "password"
Include the same password used when creating the original certificate. Also, be sure to include the quotations around your password. The resulting PFX file will be used by the WESign app to sign content for distribution. Be sure to store all of the resulting files (PVK, CER, SPC, and PFX), along with the password used to create the certificate, in a safe and secure place. DO NOT DISTRIBUTE THESE FILES! Digital certificate files are used to digitally sign content, but should not be publicly accessible at the risk of having your content compromised.
Choosing Your Content
The content that you choose to sign will be used by the app to determine the level of functionality to provide or limitations to enforce. Typically you'll want to include, at least, the Window-Eyes serial number to make sure that an app runs only for authorized copies of Window-Eyes. In addition, you may want to turn on or off various features in your app based on the type of license purchased. In that case, you would want to include the Window-Eyes serial number and pertinent license information in your content so that the app will know how much functionality to provide.
Signing Your Content
Now that you have your own digital certificate, and have decided on the information your app needs to run with the appropriate restrictions, you can use the Window-Eyes WESign app to digitally sign the content. In addition to signing the content, WESign will create a Window-Eyes App Package (WEPM) that you can provide to the end user who has paid for a valid license, and whose serial number matches that in the signed content.
Open the WESign dialog by selecting the Sign Content option from the WESign menu item in the Window-Eyes Apps menu. To successfully sign content, you will need to provide the full path to your PFX certificate, the password associated with the certificate, and the content to be signed. You may also choose to store certificate and password information so that you don't have to reenter it each time you want to sign content. Once you have provided all the required information, you can select the Sign button, which will prompt you for a name of the WEPM package that will contain your signed content. The name you choose will also be displayed in the Add/Remove Packages after the package has been installed. If your app is called My App, you may choose to call your signed content package My App License.
After the package has been successfully created, you can distribute the WEPM to the appropriate end user using your preferred method.
When the end user receives the package, they will install it like any other Window-Eyes app. The package contains a single file, using the name provided and an extension of .appkey (such as My App License.appkey). The .appkey file is a text file containing the digitally signed content. This file is copied to the end user's profile directly during the package installation.
When the installation completes, an entry for the signed content will be presented in the Window-Eyes Add/Remove Apps dialog using the name provided during the signing process.
Validating Signed Content
There are several ways an app can choose to discover the existence of signed content. The app can look for the .appkey file on launch, repeatedly look for the file in a timer, or prompt the user to select the .appkey file. The choice is up to you. Once you know that the signed content is available, you'll need to validate the content's digital signature, and compare the signature's thumbprint and subject name to existing strings within your app.
To begin, open the .appkey file, and read the contents into a variable:
Set fsObj = CreateObject("Scripting.FileSystemObject") Set txtObj = fsObj.OpenTextFile(ClientInformation.ScriptPath & "\myapp.appkey", 1) strSignedContent = txtObj.ReadAll() Set txtObj = Nothing Set fsObj = Nothing
You can then use the following verification function by passing the signed content, along with the thumbprint and subject name of the digital signature used to sign the content. If the verification process is successful, the function will return the content that you signed with the WESign app as a plain text string. If the verification process is not successful, the function will return an empty string.
Function ValidateDigitalContent(strSignedContent, strThumbprint, strSubjectName) Dim SignedData ' Begin ValidateDigitalContent = "" ' Default return value Set SignedData = CreateObject("CAPICOM.SignedData") If Not SignedData Is Nothing Then On Error Resume Next SignedData.Verify strSignedContent, False, 0 If Err.Number = 0 Then With SignedData.Signers(1).Certificate If .Thumbprint = strThumbprint And .SubjectName = strSubjectName Then ValidateDigitalContent = SignedData.Content End If End With End If On Error Goto 0 End If Set SignedData = Nothing End Function
If the validation is successful, your app can proceed to compare serial numbers, and enable or disable functionality based on the content included in the validation string.
It's important to note that, while the content you're providing to the end user is digitally signed, it is not encrypted. You may choose to encrypt your content prior to signing it with the WESign app. If you do encrypt your content, be sure to decrypt it in your app once it has been validated. You will also want to make sure that you encrypt your app so that the entire signature verification process remains unalterable.
Using digitally signed content, app developers can transport sensitive information to end users with confidence, making the prospect of paid app features more manageable.