Home > Articles > Security > Network Security

Cryptography with Java

This chapter is from the book

Cryptographic Services and Providers

In Java API terminology, cryptographic services are programming abstractions to carry out or facilitate cryptographic operations. Most often, these services are represented as Java classes with names conveying the intent of the service. For example, digital signature service, represented by java.security.Signature class, creates and verifies digital signatures. However, not all services are directly related to cryptographic operations. Take the functionality to create certificates. This is provided as a certificate factory service through service class java.security.cert.CertificateFactory.

An instance of a service is always associated with one of many algorithms or types. The algorithm determines the specific sequence of steps to be carried out for a specific operation. Similarly, the type determines the format to encode or store information with specific semantics. For example, a Signature instance could be associated with algorithm DSA (Digital Signature Algorithm) or RSA (named after the initial letters of its three inventors: Rivest, Shamir, and Adleman). Similarly, a CertificateFactory instance could be associated with certificate type X.509.

While talking about cryptographic services and their algorithms or types, we use the term algorithm for brevity, knowing well that some services will have associated types and not algorithms.

The cryptographic service classes have a distinct structure to facilitate independence from algorithm and implementation. They typically do not have public constructors and the instances are created by invoking a static method getInstance() on the service class. The algorithm or type, represented as a string, must be specified as an argument to the getInstance() method. For exammple, the following statement creates a Signature instance with "SHA1WithDSA" algorithm.

Signature sign = Siganture.getInstance("SHA1WithDSA");

Besides the algorithm, one could also specify the implementation, also known as the provider, while creating an instance of the service. This is illustrated by passing the string "SUN", and identifying a specific provider as an additional parameter.

Signature sign = Siganture.getInstance("SHA1WithDSA", "SUN");

This structure of the API allows different implementation of the same service, supporting overlapping collections of algorithms, to exist within the same program and be accessible through the same service class. We talk more about this mechanism in the next section.

As noted earlier, certain services require an algorithm whereas others require a type. As we saw, signature service requires an algorithm whereas key store service requires a type. Roughly speaking, a service representing an operation needs an algorithm and a service representing an entity or actor needs a type.

Table 3-1 lists some of the J2SE v1.4 cryptographic services and supported algorithms, with brief descriptions. A comprehensive table can be found in Appendix B.

You may find the information in Table 3-1 a bit overwhelming, but don't be alarmed. We talk more about the various services and supported algorithms later in the chapter. Just keep in mind that cryptographic services have corresponding Java classes with the same names and algorithm identifiers passed as string arguments to method invocations.

The separation of service from algorithm, coupled with the API design where a specific service instance of a particular implementation is obtained by specifying them at runtime, is the key mechanism for algorithm and implementation independence. The visible service API classes, such as Signature and CertificateFactory, act only as a mechanism to get to the real implementation class, and hence are also referred to as engine classes. We find many examples of such classes later in the chapter and also in subsequent chapters.

Table 3-1. Java Cryptographic Services

Cryptographic Service


Brief Description



Generates random numbers appropriate for use in cryptography.


DES, TripleDES, Blowfish

Generates secret keys to be used by other services with the same algorithms.



Generates a pair of public and private keys to be used by other services with the same algorithms.



Computes the digest of a message.


HmacMD5, HmacSHA1

Computes the message authentication code of a message.



Creates and verifies the digital signature of a message



Stores keys and certificates.



Creates certificates.


DES, TripleDES, Blowfish

Encrypts and decrypts messages.



Lets two parties agree on a secret key without exchanging it over an insecure medium.


As we noted, Cryptographic Service Providers, or just providers, are implementations of cryptographic services consisting of classes belonging to one or more Java packages. It is possible to have multiple providers installed within a J2SE environment, some even implementing the same service with the same algorithms. A program can either explicitly specify the provider name through an identifier string assigned by the vendor, or implicitly ask for the highest priority provider by not specifying any provider. In the last section, statement Signature.getInstance("SHA1withDSA") retrieves the implementation class of Signature implementing algorithm "SHA1withDSA" of the highest priority provider. In contrast, Signature.getInstance("SHA1withDSA", "SUN") retrieves the implementation class from the provider with the name "SUN".

A mechanism exists to specify priorities to these providers. We talk more about this mechanism in a subsequent section.

Note that JCA and JCE APIs define only the engine classes, most of them within java.security, javax.crypto and their various subpackages. The actual implementation of these classes is in various provider classes that come bundled with J2SE v1.4. It is also possible to install additional providers. We learn how to install additional providers in the section Installing and Configuring a Provider.

A few points about providers are worth noting. A provider doesn't have to implement all the services defined within JCA or JCE. Also, a provider can implement some services from one API and some from another. Which algorithms are to be supported for a specific service is also left to the provider. As you can see, the bundling of engine classes in separate APIs is quite independent of the packaging of classes within a provider.

Thankfully, there are APIs to access all the available providers, the services supported by them and other associated details. JSTK utility crypttool has a command to list the providers and related details. But before we get to that, let us understand the mechanism to achieve algorithm and implementation independence by looking at the internal structure of engine classes and their relationship with provider classes.

Algorithm and Implementation Independence

The best way to illustrate this independence is with the help of an example. Take the simple service of creating and verifying a digital signature, java.security.Signature. It has a static method getInstance() that takes the algorithm name and optionally, the provider name, as arguments and creates a concrete Signature object. The client program operates on this object, initializing it for signing by invoking the initSign() method or for verification by invoking the initVerify() method.

Under the hood, the static method getInstance() consults the singleton class java.security.Security to get the fully qualified name of the class associated with Signature service for the specified provider or, if the provider is not specified, the highest priority provider with Signature implementation for the specified algorithm. This implementation class must extend the abstract class java.security.SignatureSpi and provide the implementation of all the abstract methods. Once such a class name is found, the corresponding object is constructed using Java reflection and passed to the protected constructor of the Signature class. The Signature class keeps a reference of the newly created object in its member variable. Subsequent method invocations on Signature object operate on the object corresponding to the underlying implementation class.

The relationship of various classes and their runtime behavior is further illustrated in Figure 3-1. Class XYZProvider extends java.security.Provider and registers itself to the singleton class Security. This provider supplies the concrete implementation class XYZSignature, extending abstract class SignatureSPI.

03fig01.gifFigure 3-1. Provider Architecture for Signature Class.

Although the preceding discussion and the diagram is for Signature service, the same is true for all other cryptographic services. The point to be noted is that even though the client program uses a well-known class, the selection of the actual class implementing the service happens at runtime. This makes adding new providers with new algorithms fairly straightforward and quite transparent to the client program. Well, at least within certain limits. We come across situations when this simple framework breaks down and the client must include code that knows about specific algorithms.

Listing Providers

As we said earlier, it is possible to query a J2SE environment for currently installed providers and the cryptographic services supported by them. This ability comes in handy in writing programs that adjust their behavior based on the capabilities available within an environment and also in troubleshooting.

Java class Security keeps track of all the installed providers in the form of Provider class instances and can be queried to get this information. A Provider object contains entries for each service and information on supported algorithms.

The example program ListCSPs.java, available in the examples directory for this chapter src\jsbook\ch3\ex1, lists all the installed cryptographic service providers, indicating their name and version.

Listing 3-1. Listing Cryptographic Service Providers

// File: src\jsbook\ch3\ex1\ListCSPs.java
import java.security.Security;
import java.security.Provider;

public class ListCSPs {
  public static void main(String[] unused){
    Provider[] providers = Security.getProviders();
    for (int i = 0; i < providers.length; i++){
      String name = providers[i].getName();
      double version = providers[i].getVersion();
      System.out.println("Provider["+i+"]:: " + name + " " + version);

Compiling and running this program under J2SE v1.4.x, assuming that you are in the same directory as this file and either the CLASSPATH is not set or includes the current directory, produces the following output:

C:\ch3\ex1>%JAVA_HOME%\bin\javac ListCSPs.java
   C:\ch3\ex1>%JAVA_HOME%\bin\java ListCSPs
   Provider[0]:: SUN 1.2
   Provider[1]:: SunJSSE 1.41
   Provider[2]:: SunRsaSign 1.0
   Provider[3]:: SunJCE 1.4
   Provider[4]:: SunJGSS 1.0

You can infer from the output that J2SE v1.4.1 comes with five bundled providers and their names are: "SUN", "SunJSSE", "SunRsaSign", "SunJCE" and "SunJGSS". The same code is executed by utility crypttool with listp command, for listing providers.

Information about services implemented by a provider, aliases or different names corresponding to the same service, supported algorithms and other associated properties are stored within the Provider object as name value pairs. These name value pairs can be displayed by running the command "crypttool listp –props". However, deducing information about each service from this listing is somewhat nontrivial and hence is made available through a separate option –csinfo, for cryptographic service information. Let us look at the output of "crypttool listp –csinfo" command in Listing 3-2.

Listing 3-2. Output of "bin\crypttool listp –csinfo" command

C:\...\jstk>bin\crypttool listp -csinfo
   Provider[0]:: SUN 1.2
   Cryptographic Services::
   [0] MessageDigest    : SHA1|SHA|SHA-1
   ImplementedIn = Software
   ImplementedIn = Software
   [1] KeyStore         : JKS
   ImplementedIn = Software
   [2] Signature: SHAwithDSA|DSAWithSHA1|DSA|SHA/DSA|SHA-1/DSA|SHA1withDSA|
   ImplementedIn = Software
   KeySize = 1024
   [3] SecureRandom     : SHA1PRNG
   ImplementedIn = Software
   [4] CertPathValidator : PKIX
   ImplementedIn = Software
   ValidationAlgorithm = draft-ietf-pkix-new-part1-08.txt
   [5] KeyPairGenerator : DSA
   ImplementedIn = Software
   KeySize = 1024
   [6] CertificateFactory : X509|X.509
   [7] AlgorithmParameterGenerator : DSA
   ImplementedIn = Software
   KeySize = 1024
   [8] CertStore        : LDAP
   ImplementedIn = Software
   LDAPSchema = RFC2587
   ImplementedIn = Software
   [9] AlgorithmParameters : DSA
   ImplementedIn = Software
   [10] KeyFactory      : DSA
   ImplementedIn = Software
   [11] CertPathBuilder : PKIX
   ImplementedIn = Software
   ValidationAlgorithm = draft-ietf-pkix-new-part1-08.txt
   Provider[1]:: SunJSSE 1.41
   Cryptographic Services::
   [0] KeyStore         : PKCS12
   [1] Signature        : MD5withRSA
   [2] TrustManagerFactory : SunX509
   [3] KeyPairGenerator : RSA
   [4] SSLContext       : SSL
   [5] KeyManagerFactory : SunX509
   [6] KeyFactory       : RSA
   Provider[2]:: SunRsaSign 1.0
   Cryptographic Services::
   [0] Signature        : MD5withRSA
   [1] KeyPairGenerator : RSA
   [2] KeyFactory       : RSA
   Provider[3]:: SunJCE 1.4
   Cryptographic Services::
   [0] Cipher           : DES
   [1] KeyStore         : JCEKS
   [2] KeyPairGenerator : DiffieHellman|DH
   [3] AlgorithmParameterGenerator : DiffieHellman|DH
   [4] AlgorithmParameters : TripleDES|DESede
   [5] KeyAgreement     : DiffieHellman|DH
   [6] KeyGenerator     : HmacSHA1
   [7] SecretKeyFactory : TripleDES|DESede
   [8] KeyFactory       : DiffieHellman|DH
   [9] Mac              : HmacMD5
   Provider[4]:: SunJGSS 1.0
   Cryptographic Services::

The output contains a wealth of information about various services supported by bundled providers. To interpret the results, follow the following simple rules:

  • The left side of ":" has the service name and the right side has the algorithms or types supported.

  • More than one algorithm or type name in the same line, separated by "|" imply aliases for the same name.

  • Some of the entries have additional information in the form of name-value pairs. An example of such a name-value pair is "ImplementedIn = Software" for a number of entries.

Once you get comfortable with the output, you have figured out a lot about various cryptographic services available with J2SE SDK, v1.4. Regarding the supported services, the following observations are worth noting:

  • Cipher service in provider "SunJCE" supports only symmetric algorithms. You cannot use this provider or any other bundled provider for public-key encryption.

  • "TripleDES" and "DESede" are aliases for the same algorithm.

  • Provider "SUN" has implementation for not only JCA services but also for a number of certificate validation services. We cover certificates and other related operations in Chapter 4, PKI with Java.

  • Three different types of KeyStore are supported, each one in a different provider: "JKS" in "SUN", "JCEKS" in "SunJCE" and "PKCS12" and "SunJSSE".

If you are working with a J2SE v1.4 compliant environment from a vendor other than Sun or have installed third-party providers, the output may be different. In either case, crypttool is a good tool to explore your environment.

Installing and Configuring a Provider

Installing a provider means placing the jar file(s) having the provider classes at appropriate locations and modifying the security configuration files so that the application program is able to load and execute the provider class files. This can be done by installing the provider as a standard Java extension by placing the jar file in the jre-home\lib\ext directory where jre-home is the Java runtime software installation directory. If you have J2SE SDK, v1.4 installed in c:\j2sdk1.4 then the jre-home will be c:\j2sdk1.4\jre. If you have only the JRE (Java Runtime Environment), then jre-home will be the root directory of the JRE installation, such as c:\Program Files\Java\jre1.4.0.

It is also possible to install a provider by just making the jar file available as a component in the bootclasspath of the program. This would require launching the client program with the command "java –Xbootclasspath/a:provider-jar-file client-program-class". Just setting the CLASSPATH to include the provider jar file doesn't work.

If the provider is not installed as an extension and it is to be accessed by a program where a Security Manager is installed, then it must be granted appropriate permissions in the global or user-specific policy file java.policy. Recall that JVM running an applet will most likely have a Security Manager installed. The syntax of policy files and other details on granting specific permissions are covered in Chapter 5, Access Control. However, the brief description given below would suffice for installing a provider.

The global policy file resides in the directory jre-home\lib\security. The default location of the user specific policy file is in the user home directory. A sample policy statement granting such permission to a provider with the name "MyJCE" and class files in myjce_provider.jar kept in directory c:\myjce appears below:

grant codeBase "file:/c:/myjce/myjce_provider.jar" {
  permission java.lang.RuntimePermission "getProtectionDomain";
  permission java.security.SecurityPermission

After installation, a provider must be configured before it can be accessed by the client programs. This configuration is done either statically for the whole J2SE environment by modifying security properties file or dynamically for a given run of a program by invoking appropriate API calls from within the program.

Static configuration requires modification of the security properties file jre-home\lib\security\java.security. This file contains an entry for each provider, either bundled or installed, of the form


Here n is a number specifying the priority, 1 being the highest, and master-class-name is the fully qualified name of the class in the provider jar file that extends the class java.security.Provider. To add a provider, simply insert an entry corresponding to the provider's master class with the appropriate priority number. Note that this may require some adjustment in the priority of existing providers.

For example, after installing Cryptix JCE provider (Cryptix JCE provider is an open source implementation available from http://www.cryptix.org with lowest priority, a portion of the java.security file would look like:


#Added by Pankaj on July 22, 2002 for testing.

If you have more than one provider with the same priority, then the registration by the last provider overrides the previous registrations. Also, you must not have gaps within the priority number sequence, otherwise only the providers with consecutive priorities starting at 1 are registered. If there is a typo in the fully qualified name of the master class then the corresponding provider is not registered. All this happens silently without any warning, so you must be careful while modifying the security properties file.

You can check for successful configuration by running the command "crypttool listp". An invocation of this program should list all the providers, including the new ones, in the same order as the specified priority numbers. A frequent mistake, especially on development machines with multiple Java runtime software installed, is not realizing that the runtime environment of the java command may not be the same as the one you just configured. This is easily rectified by executing the command with %JAVA_HOME%\bin\java in place of java to launch the right JVM. Utility crypttool picks up the java executable from %JAVA_HOME%\bin directory, so make sure that the value of environment variable JAVA_HOME matches the Java installation you just configured.

A provider is dynamically configured within the client program code by calling addProvider or insertProviderAt method of Security class. For this to work, appropriate permission must be granted to the client code. For example, the following statement in the policy file java.policy provides the adequate permission to all code from directory c:\myclient.

grant codeBase "file:/c:/myclient/" {
  permission java.security.SecurityPermission "insertProviderAt.*";
  permission java.security.SecurityPermission "addProvider.*";

Another thing to keep in mind is that the JCE engine authenticates the provider by verifying the signature on the code. The verification step looks for a signature by JCE Code Signing CA or a CA whose certificate has been signed by it. This is not a problem for bundled or commercial providers, as they are signed with appropriate private keys, but it becomes an issue with your own implementation of a JCE provider and most of the open source providers. For example, when I installed the "CryptixCrypto" provider and launched a program accessing one of its services, the exception java.security.NoSuchProviderException was thrown with a message saying: JCE cannot authenticate the provider CryptixCrypto.

If you do want to play with an unsigned provider during development, you can bypass the JCE engine by specifying an alternate JCE implementation. In the case of Cryptix provider, one way to do this is simply by removing the JDK's jce.jar file from jre-home\lib as the Cryptix provider comes with its own JCE classes.

Another option is to use the open source JCE provider from Legion of the Bouncy Castle, available from http://www.bouncycastle.org. This provider comes with an appropriate signed jar file and supports a wide variety of services and algorithms. For release 1.18 (the current one in March 2003), you should download a file named bcprov-jdk14-118.jar and place it in jre-home\lib\ext directory and add the following line in your java.security file:


If you do install this provider, run command "bin\crypttool listp" to get a list of active providers; and if this succeeds and shows BC as a provider, then command "bin\crypttool listp –provider BC –csinfo" to get a listing of available services and algorithms supported with this provider.

To recap, you must pay attention to the following while installing a security provider:

  • The provider jar file has been placed in the standard extension directory or its path is specified through –Xbootclasspath argument to JVM.

  • The provider jar has been granted appropriate permissions. This is required only if the program is running under a Security Manager. This is likely to be the case if your program is running within a container.

  • An appropriate CA has signed the provider jar.

Why is installing a security provider so complicated? Compromise of a security provider can easily compromise all the security provided by cryptography. Hence, it is imperative that proper safeguards are in place. A number of the above mentioned steps are about ensuring that only trusted code is used as a security provider.

Why would someone want to use a third-party provider? Here are some good reasons:

  • You need your Java application to be integrated into an existing environment that uses algorithms and/or types not supported by bundled providers.

  • You bought special hardware to speed up your application but use of this hardware requires using the vendor's provider.

  • The algorithms supported by the bundled providers are not strong enough for your requirements.

  • You live in a country where you can only download the J2SE SDK with "limited" cryptography but want to use "unlimited" cryptography. We will talk more about this later in the section Limited versus Unlimited Cryptography.

  • You invented a new algorithm or better implementation of an existing algorithm and want to use it.

Whether you use the provider supplied with J2SE v1.4.x SDK or install your own, the programs using the cryptographic services remain the same.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information

To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.


Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.


If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information

Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.


This site is not directed to children under the age of 13.


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information

If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information

Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents

California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure

Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact

Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice

We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020