Movatterモバイル変換


[0]ホーム

URL:


Skip toContent

Java PKCS#11 Reference Guide


1.0Introduction

2.0Sun PKCS#11 Provider

2.1Requirements
2.2Configuration
2.3Accessing Network Security Services(NSS)

3.0Application Developers

3.1Token Login
3.2Token Keys
3.3Delayed ProviderSelection
3.4JAAS KeyStoreLoginModule
3.5Tokens as JSSE Keystores and TrustStores

4.0Tools

4.1KeyTool and JarSigner
4.2PolicyTool

5.0Provider Developers

5.1Provider Services
5.1.1Instantiating EngineClasses
5.1.2Parameter Support

Appendix ASun PKCS#11 Provider's SupportedAlgorithms

Appendix BSun PKCS#11Provider's KeyStore Restrictions

Appendix CExample Provider


1.0 Introduction

The Java platform defines a set of programming interfaces forperforming cryptographic operations. These interfaces arecollectively known as the Java Cryptography Architecture (JCA) andthe Java Cryptography Extension (JCE). Specifications are availableatthe Java SE Security Documentationpage.

The cryptographic interfaces are provider-based. Specifically,applications talk to Application Programming Interfaces (APIs), andthe actual cryptographic operations are performed in configuredproviders which adhere to a set of Service Provider Interfaces(SPIs). This architecture supports different providerimplementations. Some providers may perform cryptographicoperations in software; others may perform the operations on ahardware token (for example, on a smartcard device or on a hardwarecryptographic accelerator).

The Cryptographic Token Interface Standard, PKCS#11, is producedby RSA Security and defines native programming interfaces tocryptographic tokens, such as hardware cryptographic acceleratorsand Smartcards. To facilitate the integration of native PKCS#11tokens into the Java platform, a new cryptographic provider, theSun PKCS#11 provider, has been introduced into the J2SE 5.0release. This new provider enables existing applications written tothe JCA and JCE APIs to access native PKCS#11 tokens. Nomodifications to the application are required. The only requirementis the proper configuration of the provider into the JavaRuntime.

Although an application canmake use of most PKCS#11 features using existing APIs, someapplications might need more flexibility and capabilities. Forexample, an application might want to deal with Smartcards beingremoved and inserted dynamically more easily. Or, a PKCS#11 tokenmight require authentication for some non-key-related operationsand therefore, the application must be able to log into the tokenwithout using keystore. In J2SE 5.0, the JCA was enhanced to allowapplications greater flexibility in dealing with differentproviders.

This document describes how native PKCS#11 tokens can beconfigured into the Java platform for use by Java applications. Italso describes the enhancements that were made to the JCA to makeit easier for applications to deal with different types ofproviders, including PKCS#11 providers.

2.0 Sun PKCS#11 Provider

The Sun PKCS#11 provider, in contrast to most other providers,does not implement cryptographic algorithms itself. Instead, itacts as a bridge between the Java JCA and JCE APIs and the nativePKCS#11 cryptographic API, translating the calls and conventionsbetween the two. This means that Java applications calling standardJCA and JCE APIs can, without modification, take advantage ofalgorithms offered by the underlying PKCS#11 implementations, suchas, for example,

Note that Java SE only facilitates accessing native PKCS#11implementations, it does not itself include a native PKCS#11implementation. However, cryptographic devices such as Smartcardsand hardware accelerators often come with software that includes aPKCS#11 implementation, which you need to install and configureaccording to manufacturer's instructions.

2.1 Requirements

The Sun PKCS#11 provider is supported on Solaris (SPARC and x86)and Linux (x86) in both 32-bit and 64-bit Java processes. It isalso supported on 32-bit Windows (x86) but not currently on 64-bitWindows platforms due to the lack of suitable PKCS#11 libraries.

The Sun PKCS#11 provider requires an implementation of PKCS#11v2.0 or later to be installed on the system. This implementationmust take the form of a shared-object library (.so on Solaris andLinux) or dynamic-link library (.dll on Windows). Please consultyour vendor documentation to find out if your cryptographic deviceincludes such a PKCS#11 implementation, how to configure it, andwhat the name of the library file is.

The Sun PKCS#11 provider supports a number of algorithms,provided that the underlying PKCS#11 implementation offers them.The algorithms and their corresponding PKCS#11 mechanisms arelisted in the table inAppendix A.

2.2 Configuration

The Sun PKCS#11 provider is implemented by the main classsun.security.pkcs11.SunPKCS11 and accepts the fullpathname of a configuration file as an argument. To use theprovider, you must first install it by using theJava CryptographyArchitecture (JCA). As with all JCA providers, installation ofthe provider can be done either statically or programmatically. Toinstall the provider statically, add the provider to the JavaSecurity properties file($JAVA_HOME/lib/security/java.security). For example,here's a fragment of thejava.security file that installsthe Sun PKCS#11 provider with the configuration file/opt/bar/cfg/pkcs11.cfg.
# configuration for security providers 1-6 omittedsecurity.provider.7=sun.security.pkcs11.SunPKCS11 /opt/bar/cfg/pkcs11.cfg
To install the provider dynamically, create an instance of theprovider with the appropriate configuration filename and theninstall it. Here is an example.
String configName = "/opt/bar/cfg/pkcs11.cfg";Provider p = new sun.security.pkcs11.SunPKCS11(configName);Security.addProvider(p);

To use more than one slot per PKCS#11 implementation, or to usemore than one PKCS#11 implementation, simply repeat theinstallation for each with the appropriate configuration file. Thiswill result in a Sun PKCS#11 provider instance for each slot ofeach PKCS#11 implementation.

The configuration file is a text file that contains entries inthe following format.

attribute =value The valid values forattribute andvalue are described in the table inthis section. The two mandatory attributes arename andlibrary. Here is a sample configuration file.
name = FooAcceleratorlibrary = /opt/foo/lib/libpkcs11.so
Comments are denoted by lines starting with the# (number)symbol.

AttributeValueDescription
librarypathname of PKCS#11 implementationThis is the full pathname (including extension) of the PKCS#11implementation; the format of the pathname is platform dependent.For example,/opt/foo/lib/libpkcs11.so might be thepathname of a PKCS#11 implementation on Solaris and Linux whileC:\foo\mypkcs11.dll might be one on Windows.
namename suffix of this provider instanceThis string is concatenated with the prefixSunPKCS11-to produce this provider instance's name (that is, the stringreturned by itsProvider.getName() method). Forexample, if thename attribute is"FooAccelerator", then the provider instance's name willbe"SunPKCS11-FooAccelerator".
descriptiondescription of this provider instanceThis string will be returned by the provider instance'sProvider.getInfo() method. If none is specified, adefault description will be returned.
slotslot idThis is the id of the slot that this provider instance is to beassociated with. For example, you would use1 for theslot with the id1 under PKCS#11. At most one ofslot orslotListIndex may be specified. Ifneither is specified, the default is aslotListIndex of0.
slotListIndexslot indexThis is the slot index that this provider instance is to beassociated with. It is the index into the list of all slotsreturned by the PKCS#11 functionC_GetSlotList. Forexample,0 indicates the first slot in the list. Atmost one ofslot orslotListIndex may bespecified. If neither is specified, the default is aslotListIndex of0.
enabledMechanismsbrace enclosed, whitespace-separated list of PKCS#11 mechanismsto enableThis is the list PKCS#11 mechanisms that this provider instanceshould use, provided that they are supported by both the SunPKCS#11 provider and PKCS#11 token. All other mechanisms will beignored. Each entry in the list is the name of a PKCS#11 mechanism.Here is an example that lists two PKCS#11 mechanisms.
enabledMechanisms = {  CKM_RSA_PKCS  CKM_RSA_PKCS_KEY_PAIR_GEN}
At most one ofenabledMechanisms ordisabledMechanisms may be specified. If neither isspecified, the mechanisms enabled are those that are supported byboth theSun PKCS#11 provider and the PKCS#11token.
disabledMechanismsbrace enclosed, whitespace-separated list of PKCS#11 mechanismsto disableThis is the list of PKCS#11 mechanism that this providerinstance should ignore. Any mechanism listed will be ignored by theprovider, even if they are supported by the token and the SunPKCS#11 provider. The stringsSecureRandom andKeyStore may be specified to disable those services.

At most one ofenabledMechanisms ordisabledMechanisms may be specified. If neither isspecified, the mechanisms enabled are those that are supported byboth theSun PKCS#11 provider and the PKCS#11token.

attributessee belowTheattributes option can be used to specifyadditional PKCS#11 that should be set when creating PKCS#11 keyobjects. This makes it possible to accommodate tokens that requireparticular attributes. For details, see the section below.

Attributes Configuration

The attributes option allows you to specify additional PKCS#11attributes that should be set when creating PKCS#11 key objects. Bydefault, the SunPKCS11 provider only specifies mandatory PKCS#11attributes when creating objects. For example, for RSA public keysit specifies the key type and algorithm (CKA_CLASS andCKA_KEY_TYPE) and the key values for RSA public keys (CKA_MODULUSand CKA_PUBLIC_EXPONENT). The PKCS#11 library you are using willassign implementation specific default values to the otherattributes of an RSA public key, for example that the key can beused to encrypt and verify messages (CKA_ENCRYPT and CKA_VERIFY =true).

Theattributes option can be used if you do not likethe default values your PKCS#11 implementation assigns or if yourPKCS#11 implementation does not support defaults and requires avalue to be specified explicitly. Note that specifying attributesthat your PKCS#11 implementation does not support or that areinvalid for the type of key in question may cause the operation tofail at runtime.

The option can be specified zero or more times, the options areprocessed in the order specified in the configuration file asdescribed below. Theattributes option has the format:

attributes(operation, keytype, keyalgorithm) = {  name1 = value1  [...]}
Valid values foroperation are:Valid values forkeytype areCKO_PUBLIC_KEY,CKO_PRIVATE_KEY, andCKO_SECRET_KEY, for public,private, and secret keys, respectively, and* to match anytype of key.

Valid values forkeyalgorithm are one of theCKK_xxx constants from the PKCS#11 specification, or* to match keys of any algorithm. The algorithms currentlysupported by the SunPKCS11 provider are CKK_RSA, CKK_DSA, CKK_DH,CKK_AES, CKK_DES, CKK_DES3, CKK_RC4, CKK_BLOWFISH, andCKK_GENERIC.

The attribute names and values are specified as a list of one ormore name-value pairs.name must be aCKA_xxxconstant from the PKCS#11 specification, for exampleCKA_SENSITIVE.value can be one of thefollowing:

If theattributes option is specified multiple times, theentries are processed in the order specified with the attributesaggregated and later attributes overriding earlier ones. Forexample, consider the following configuration file excerpt:
attributes(*,CKO_PRIVATE_KEY,*) = {  CKA_SIGN = true}attributes(*,CKO_PRIVATE_KEY,CKK_DH) = {  CKA_SIGN = null}attributes(*,CKO_PRIVATE_KEY,CKK_RSA) = {  CKA_DECRYPT = true}
The first entry says to specifyCKA_SIGN = true for allprivate keys. The second option overrides that withnullfor Diffie-Hellman private keys, so theCKA_SIGN attributewill not specified for them at all. Finally, the third option saysto also specifyCKA_DECRYPT = true for RSA private keys.That means RSA private keys will have bothCKA_SIGN = trueandCKA_DECRYPT = true set.

There is also a special form of theattributes option.You can writeattributes = compatibility in theconfiguration file. That is a shortcut for a whole set of attributestatements. They are designed to provider maximum compatibilitywith existing Java applications, which may expect, for example, allkey components to be accessible and secret keys to be usable forboth encryption and decryption. Thecompatibilityattributes line can be used together with otherattributeslines, in which case the same aggregation and overriding rulesapply as described earlier.

2.3 Accessing Network Security Services (NSS)

NetworkSecurity Services (NSS) is a set of open source securitylibraries used by the Mozilla/Firefox browsers, Sun's JavaEnterprise System server software, and a number of other products.Its crypto APIs are based on PKCS#11 but it includes specialfeatures that are outside of the PKCS#11 standard. The Sun PKCS#11provider includes code to interact with these NSS specificfeatures, including several NSS specific configuration directives,which are described below.

For best results, we recommend that you use the latest versionof NSS available. It should be at least version 3.12.

The Sun PKCS#11 provider uses NSS specific code when any of thenss configuration directives described below are used.In that case, the regular configuration commandslibrary,slot, andslotListIndex cannot be used.

AttributeValueDescription
nssLibraryDirectorydirectory containing the NSS and NSPR librariesThis is the full pathname of the directory containing the NSSandNSPRlibraries. It must be specified unless NSS has already been loadedand initialized by another component running in the same process asthe Java VM.

Depending on your platform, you may have to setLD_LIBRARY_PATH orPATH (on Windows) toinclude this directory in order to allow the operating system tolocate the dependent libraries.

nssSecmodDirectorydirectory containing the NSS DB filesThe full pathname of the directory containing the NSSconfiguration and key information (secmod.db,key3.db, andcert8.db). This directivemust be specified unless NSS has already been initialized byanother component (see above) or NSS is used without database filesas described below.
nssDbModeone ofreadWrite,readOnly, andnoDbThis directives determines how the NSS database is accessed. Inread-write mode, full access is possible but only one process at atime should be accessing the databases. Read-only mode disallowsmodifications to the files.

The noDb mode allows NSS to be used without database filespurely as a cryptographic provider. It is not possible to createpersistent keys using the PKCS11 KeyStore.

nssModuleone ofkeystore,crypto,fips, andtrustanchorsNSS makes its functionality available using several differentlibraries and slots. This directive determines which of thesemodules is accessed by this instance of SunPKCS11.

Thecrypto module is the default innoDb mode. It supports crypto operations without loginbut no persistent keys.

Thefips module is the default if the NSSsecmod.db has been set to FIPS-140 compliant mode. Inthis mode, NSS restricts the available algorithms and the PKCS#11attributes with which keys can be created.

Thekeystore module is the default in otherconfigurations. It supports persistent keys using the PKCS11KeyStore, which are stored in the NSS DB files. This modulerequires login.

Thetrustanchors module enables access to NSS trustanchor certificates via the PKCS11 KeyStore, ifsecmod.db has been configured to include the trustanchor library.

Example SunPKCS11 configuration files for NSS

NSS as a pure cryptography provider
name = NSScryptonssLibraryDirectory = /opt/tests/nss/libnssDbMode = noDbattributes = compatibility
NSS as a FIPS 140 compliant crypto token:
name = NSSfipsnssLibraryDirectory = /opt/tests/nss/libnssSecmodDirectory = /opt/tests/nss/fipsdbnssModule = fips

3.0 Application Developers

Java applications can use the existing JCA and JCE APIs toaccess PKCS#11 tokens via the Sun PKCS#11 provider. This issufficient for many applications but it might be difficult for anapplication to deal with certain PKCS#11 features, such asunextractable keys and dynamically changing Smartcards.Consequently, a number of enhancements were made to the APIs tobetter support applications using certain PKCS#11 features. Theseenhancements are discussed in this section.

3.1 Token Login

Certain PKCS#11 operations, such as accessing private keys,require a login using a Personal Identification Number, or PIN,before the operations can proceed. The most common type ofoperations that require login are those that deal with keys on thetoken. In a Java application, such operations often involve firstloading the keystore. When accessing the PKCS#11 token as akeystore via thejava.security.KeyStore class, you cansupply the PIN in the password input parameter to theload method, similar to how applications initialize a keystoreprior to J2SE 5.0. The PIN will then be used by the Sun PKCS#11provider for logging into the token. Here is an example.

char[] pin = ...; KeyStore ks = KeyStore.getInstance("PKCS11");ks.load(null, pin);

This is fine for an application that treats PKCS#11 tokens asstatic keystores. For an application that wants to accommodatePKCS#11 tokens more dynamically, such as Smartcards being insertedand removed, you can use the newKeyStore.Builder class.Here is an example of how to initialize the builder for a PKCS#11keystore with a callback handler.

KeyStore.CallbackHandlerProtection chp =    new KeyStore.CallbackHandlerProtection(new MyGuiCallbackHandler());KeyStore.Builder builder =    KeyStore.Builder.newInstance("PKCS11", null, chp);

For the Sun PKCS#11 provider, the callback handler must be ableto satisfy aPasswordCallback, which is used to prompt theuser for the PIN. Whenever the application needs access to thekeystore, it uses the builder as follows.

KeyStore ks = builder.getKeyStore();Key key = ks.getKey(alias, null);

The builder will prompt for a password as needed using thepreviously configured callback handler. The builder will prompt fora password only for the initial access. If the user of theapplication continues using the same Smartcard, the user will notbe prompted again. If the user removes and inserts a differentSmartCard, the builder will prompt for a password for the newcard.

Depending on the PKCS#11 token, there may be non-key-relatedoperations that also require token login. Applications that usesuch operations can use the newly introducedjava.security.AuthProviderclass. TheAuthProvider class extends fromjava.security.Provider and defines methods to performlogin and logout operations on a provider, as well as to set acallback handler for the provider to use.

For the Sun PKCS#11 provider, the callback handler must be ableto satisfy aPasswordCallback, which is used to prompt theuser for the PIN.

Here is an example of how an application might use anAuthProvider to log into the token.

AuthProvider aprov = (AuthProvider)Security.getProvider("SunPKCS11");aprov.login(subject, new MyGuiCallbackHandler());

3.2 Token Keys

JavaKey objects may or may not contain actual keymaterial.

Applications and providers must use the correct interfaces torepresent these different types of Key objects. Software Keyobjects (or any Key object that has access to the actual keymaterial) should implement the interfaces in thejava.security.interfacesandjavax.crypto.interfacespackages (such asDSAPrivateKey). Key objects representingunextractable token keys should only implement the relevant genericinterfaces in thejava.securityandjavax.cryptopackages (PrivateKey,PublicKey, orSecretKey). Identification of the algorithm of a keyshould be performed using theKey.getAlgorithm()method.

Applications should note that a Key object for an unextractabletoken key can only be used by the provider associated with thattoken.

3.3 Delayed Provider Selection

Prior to J2SE 5.0, the Java cryptographygetInstance()methods, such asCipher.getInstance("AES"), returned theimplementation from the first provider that implemented therequested algorithm. This is problematic if an application attemptsto use aKey object for an unextractable token key with aprovider that only accepts software key objects. In such a case,the provider would throw anInvalidKeyException. This isan issue for theCipher,KeyAgreement,Mac, andSignature classes.

J2SE 5.0, addresses this issuebydelaying the selection of the provider until the relevantinitialization method is called. The initialization method acceptsaKey object and can determine at that point whichprovider can accept the specifiedKey object. This ensuresthat the selected provider can use the specifiedKeyobject. The following represents the affected initializationmethods.

Furthermore, if an application calls the initialization methodmultiple times (each time with a different key, for example), theproper provider for the given key is selected each time. In otherwords, a different provider may be selected for each initializationcall.

Although this delayed provider selection is hidden from theapplication, it does affect the behavior of thegetProvider() method forCipher,KeyAgreement,Mac, andSignature. IfgetProvider() is calledbefore theinitialization operation has occurred (and therefore beforeprovider selection has occurred), then the first provider thatsupports the requested algorithm is returned. This may not be thesame provider as the one selectedafter the initializationmethod is called. IfgetProvider() is calledafter the initialization operation has occurred, then theactual selected provider is returned. It is recommended thatapplications only callgetProvider() after they havecalled the relevant initialization method.

In addition togetProvider(), the followingadditional methods are similarly affected.

3.4 JAAS KeyStoreLoginModule

Java SE comes with a JAAS keystore login module,KeyStoreLoginModule that allows an application toauthenticate using its identity in a specified keystore. Afterauthentication, the application would have acquire its principaland credentials information (certificate and private key) from thekeystore. By using this login module and configuring it to use aPKCS#11 token as a keystore, the application can acquire thisinformation from a PKCS#11 token.

Use the following options to configure theKeyStoreLoginModule to use a PKCS#11 token as thekeystore.

wheresome_pin_url is the location of the PIN. If thekeyStorePasswordURL option is omitted, then the loginmodule will get the PIN via the application's callback handler,supplying it with aPasswordCallback. Here is an exampleof a configuration file that uses a PKCS#11 token as a keystore.
other {    com.sun.security.auth.module.KeyStoreLoginModule required        keyStoreURL="NONE"  keyStoreType="PKCS11"  keyStorePasswordURL="file:/home/joe/scpin";};

If more than one Sun PKCS#11 provider has been configureddynamically or in thejava.security security propertiesfile, you can use thekeyStoreProvider option to target aspecific provider instance. The argument to this option is the nameof the provider. For the Sun PKCS#11 provider, the provider name isof the formSunPKCS11-TokenName, whereTokenName is the name suffix that the providerinstance has been configured with, as detailed in theconfiguration attributes table. For example, thefollowing configuration file names the PKCS#11 provider instancewith name suffixSmartCard.

other {    com.sun.security.auth.module.KeyStoreLoginModule required        keyStoreURL="NONE"  keyStoreType="PKCS11"  keyStorePasswordURL="file:/home/joe/scpin"  keyStoreProvider="SunPKCS11-SmartCard";};

Some PKCS#11 tokens support login via aprotectedauthentication path. For example, a Smartcard may have adedicated PIN-pad to enter the pin. Biometric devices will alsohave their own means to obtain authentication information. If thePKCS#11 token has a protected authentication path, then use theprotected=true option and omit thekeyStorePasswordURL option. Here is an example of aconfiguration file for such a token.

other {    com.sun.security.auth.module.KeyStoreLoginModule required        keyStoreURL="NONE"  keyStoreType="PKCS11"  protected=true;};

3.5 Tokens as JSSE Keystore and Trust Stores

To use PKCS#11 tokens as JSSE keystores or trust stores, the JSSEapplication can use the APIsdescribedpreviously to instantiate aKeyStore that is backed bya PKCS#11 token and pass it to its key manager and trust manager.The JSSE application will then have access to the keys on thetoken.

JSSE also supports configuring the use of keystores and truststores via system properties, as described in theJSSE Reference Guide. Touse a PKCS#11 token as a keystore or trust store, set thejavax.net.ssl.keyStoreType andjavax.net.ssl.trustStoreType system properties,respectively, to "PKCS11", and set thejavax.net.ssl.keyStore andjavax.net.ssl.trustStore system properties, respectively,toNONE. To specify the use of a specific providerinstance, use thejavax.net.ssl.keyStoreProvider andjavax.net.ssl.trustStoreProvider system properties (e.g.,"SunPKCS11-SmartCard").

4.0 Tools

In J2SE 5.0, thesecurity tools were updatedto support operations using the new Sun PKCS#11 provider. Thechanges are discussed below.

4.1 KeyTool and JarSigner

If the Sun PKCS#11 provider has been configured in thejava.security security properties file (located in the$JAVA_HOME/lib/security directory of the Java runtime),then keytool and jarsigner can be used to operate on the PKCS#11token by specifying the following options.

Here an example of a command to list the contents of the configuredPKCS#11 token.
keytool -keystore NONE -storetype PKCS11 -list
The PIN can be specified using the -storepass option. If none hasbeen specified, then keytool and jarsigner will prompt for thetoken PIN. If the token has a protected authentication path (suchas a dedicated PIN-pad or a biometric reader), then the-protected option must be specified, and no passwordoptions can be specified.

If more than one Sun PKCS#11 provider has been configured in thejava.security security properties file, you can use the-providerName option to target a specific providerinstance. The argument to this option is the name of theprovider.

For the Sun PKCS#11 provider,providerName is of the formSunPKCS11-TokenName, whereTokenName is the name suffix that the providerinstance has been configured with, as detailed in theconfiguration attributes table. For example, thefollowing command lists the contents of the PKCS#11 keystoreprovider instance with name suffixSmartCard.
keytool -keystore NONE -storetype PKCS11 \        -providerName SunPKCS11-SmartCard \        -list

If the Sun PKCS#11 provider has not been configured in thejava.security security properties file, you can use thefollowing options to instruct keytool and jarsigner to install theprovider dynamically.

ConfigFilePath is the path to the token configuration file.Here is an example of a command to list a PKCS#11 keystore when theSun PKCS#11 provider has not been configured in thejava.security file.
keytool -keystore NONE -storetype PKCS11 \        -providerClass sun.security.pkcs11.SunPKCS11 \        -providerArg /foo/bar/token.config \        -list

4.2 PolicyTool

Prior to J2SE 5.0, thekeystore entry in thedefault policy implementation had thefollowing syntax.

keystore "some_keystore_url", "keystore_type";
This syntax was inadequate for accessing a PKCS#11 keystore becausesuch access usually required a PIN, and there might be multiplePKCS#11 provider instances. To accommodate these requirements, thekeystore entry syntax has been updated in J2SE 5.0, to thefollowing.
keystore "some_keystore_url", "keystore_type", "keystore_provider";keystorePasswordURL "some_password_url";
Wherekeystore_provider is the keystore provider name (forexample,"SunPKCS11-SmartCard"), andsome_password_url is a URL pointing to the location of thetoken PIN. Bothkeystore_provider and thekeystorePasswordURL line are optional. Ifkeystore_provider has not been specified, then the firstconfigured provider that supports the specified keystore type isused. If thekeystorePasswordURL line has not beenspecified, then no password is used.

The following is an example keystore policy entry for a PKCS#11token.

keystore "NONE", "PKCS11", "SunPKCS11-SmartCard";keystorePasswordURL "file:/foo/bar/passwordFile";

5.0 Provider Developers

J2SE 5.0 introduces new facilities in thejava.security.Providerclass for provider implementations to more easily support PKCS#11tokens and cryptographic services in general. These new facilitiesare discussed below.

SeeAppendix C for an example ofa simple provider designed to demonstrate the new facilities.

5.1 Provider Services

As described in the above provider documentation, prior to J2SE5.0, providers were required to createjava.util.Propertyentries describing the services they supported. For each serviceimplemented by the provider, there must be a property whose name isthe type of service (Cipher,Signature, etc),followed by a period and the name of the algorithm to which theservice applies. The property value must specify the fullyqualified name of the class implementing the service. Here is anexample of a provider settingKeyAgreement.DiffieHellmanproperty to have the valuecom.sun.crypto.provider.DHKeyAgreement.

put("KeyAgreement.DiffieHellman",       "com.sun.crypto.provider.DHKeyAgreement")

J2SE 5.0 introduces a new public static nested class,Provider.Service,to help better encapsulate the properties of a provider service(including its type, attributes, algorithm name, and algorithmaliases). Providers can instantiateProvider.Serviceobjects and register them by calling theProvider.putService() method. This is equivalent tocreating aProperty entry and calling theProvider.put() method (as was done prior to J2SE 5.0).Note that legacyProperty entries registered viaProvider.put are still supported.

Here is an example of a provider creating aServiceobject with theKeyAgreement type, for theDiffieHellman algorithm, implemented by the classcom.sun.crypto.provider.DHKeyAgreement.

Service s = new Service(this, "KeyAgreement", "DiffieHellman",    "com.sun.crypto.provider.DHKeyAgreement", null, null);putService(s);

UsingProvider.Service objects instead of legacyProperty entries has a couple of major benefits. Onebenefit is that it allows the provider to have greater flexibilitywheninstantiating engine classes.Another benefit is that it allows the provider to testparameter validity. These features arediscussed in detail next.

5.1.1 Instantiating Engine Classes

Prior to J2SE 5.0, the Java Cryptography framework looked up theprovider property for a particular service and directlyinstantiated the engine class registered for that property. J2SE5.0, has the same behavior by default, but allows the provider tooverride this behavior and instantiate the engine class for therequested service itself.

To override the default behavior, the provider overrides theProvider.Service.newInstance() method to add its customerbehavior. For example, the provider might call a customconstructor, or might perform initialization using information notaccessible outside the provider (or that are only known by theprovider).

5.1.2 Parameter Support

The Java Cryptography framework may attempt a fast check todetermine whether a provider's service implementation can use anapplication-specified parameter. To perform this fast check, theframework callsProvider.Service.supportsParameter().

In J2SE 5.0, the framework relies on this fast test duringdelayed provider selection. When anapplication invokes aninitialization methodand passes it aKey object, the framework asks anunderlying provider whether it supports the object by calling itsService.supportsParameter() method. IfsupportsParameter() returnsfalse, theframework can immediately remove that provider from consideration.IfsupportsParameter() returnstrue, theframework passes theKey object to that provider'sinitialization engine class implementation. A provider thatrequires softwareKey objects should override this methodto returnfalse when it is passed non-software keys.Likewise, a provider for a PKCS#11 token that containsunextractable keys should only returntrue forKey objects that it created, and which thereforecorrespond to theKeys on its respective token.

Note that the default implementation ofsupportsParameter() returnstrue. Thisallows existing providers to work without modification. However,because of this lenient default implementation, the framework mustbe prepared to catch exceptions thrown by providers that reject theKey object inside their initialization engine classimplementations. The framework treats these cases the same as whensupportsParameter() returnsfalse.

Appendix A: Sun PKCS#11 Provider's Supported Algorithms

The following table lists the Java algorithms supported by the SunPKCS#11 provider and corresponding PKCS#11 mechanisms needed tosupport them. When multiple mechanisms are listed, they are givenin the order of preference and any one of them is sufficient. Notethat SunPKCS11 can be instructed to ignore mechanisms by using thedisabledMechanisms andenabledMechanismsconfiguration directives.

For Elliptic Curve mechanisms, SunPKCS11 will only use keys thatuse thenamedCurve choice as encoding for theparameters and only allow the uncompressed point format. The SunPKCS#11 provider assumes that a token supports all standard nameddomain parameters.

Java AlgorithmPKCS#11 Mechanisms
Signature.MD2withRSACKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509
Signature.MD5withRSACKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509
Signature.SHA1withRSACKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509
Signature.SHA256withRSACKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509
Signature.SHA384withRSACKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509
Signature.SHA512withRSACKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509
Signature.SHA1withDSACKM_DSA_SHA1, CKM_DSA
Signature.NONEwithDSACKM_DSA
Signature.SHA1withECDSACKM_ECDSA_SHA1, CKM_ECDSA
Signature.SHA256withECDSACKM_ECDSA
Signature.SHA384withECDSACKM_ECDSA
Signature.SHA512withECDSACKM_ECDSA
Signature.NONEwithECDSACKM_ECDSA
Cipher.RSA/ECB/PKCS1PaddingCKM_RSA_PKCS
Cipher.ARCFOURCKM_RC4
Cipher.DES/CBC/NoPaddingCKM_DES_CBC
Cipher.DESede/CBC/NoPaddingCKM_DES3_CBC
Cipher.AES/CBC/NoPaddingCKM_AES_CBC
Cipher.Blowfish/CBC/NoPaddingCKM_BLOWFISH_CBC
Cipher.RSA/ECB/NoPaddingCKM_RSA_X_509
Cipher.AES/CTR/NoPaddingCKM_AES_CTR
KeyAgreement.ECDHCKM_ECDH1_DERIVE
KeyAgreement.DiffieHellmanCKM_DH_PKCS_DERIVE
KeyPairGenerator.RSACKM_RSA_PKCS_KEY_PAIR_GEN
KeyPairGenerator.DSACKM_DSA_KEY_PAIR_GEN
KeyPairGenerator.ECCKM_EC_KEY_PAIR_GEN
KeyPairGenerator.DiffieHellmanCKM_DH_PKCS_KEY_PAIR_GEN
KeyGenerator.ARCFOURCKM_RC4_KEY_GEN
KeyGenerator.DESCKM_DES_KEY_GEN
KeyGenerator.DESedeCKM_DES3_KEY_GEN
KeyGenerator.AESCKM_AES_KEY_GEN
KeyGenerator.BlowfishCKM_BLOWFISH_KEY_GEN
Mac.HmacMD5CKM_MD5_HMAC
Mac.HmacSHA1CKM_SHA_1_HMAC
Mac.HmacSHA256CKM_SHA256_HMAC
Mac.HmacSHA384CKM_SHA384_HMAC
Mac.HmacSHA512CKM_SHA512_HMAC
MessageDigest.MD2CKM_MD2
MessageDigest.MD5CKM_MD5
MessageDigest.SHA1CKM_SHA_1
MessageDigest.SHA-256CKM_SHA256
MessageDigest.SHA-384CKM_SHA384
MessageDigest.SHA-512CKM_SHA512
KeyFactory.RSAAny supported RSA mechanism
KeyFactory.DSAAny supported DSA mechanism
KeyFactory.ECAny supported EC mechanism
KeyFactory.DiffieHellmanAny supported Diffie-Hellman mechanism
SecretKeyFactory.ARCFOURCKM_RC4
SecretKeyFactory.DESCKM_DES_CBC
SecretKeyFactory.DESedeCKM_DES3_CBC
SecretKeyFactory.AESCKM_AES_CBC
SecretKeyFactory.BlowfishCKM_BLOWFISH_CBC
SecureRandom.PKCS11CK_TOKEN_INFO has the CKF_RNG bit set
KeyStore.PKCS11Always available

Appendix B: Sun PKCS#11 provider's KeyStore Requirements

The following describes the requirements placed by the SunPKCS#11 Provider's KeyStore implementation on the underlying nativePKCS#11 library.Note that changes may be made in futurereleases to maximize interoperability with as many existing PKCS#11libraries as possible.

Read-Only Access

To map existing objects stored on a PKCS#11 token to KeyStoreentries, the Sun PKCS#11 Provider's KeyStore implementationperforms the following operations.

  1. A search for all private key objects on the token is performedby calling C_FindObjects[Init|Final]. The search template includesthe following attributes:
    • CKA_TOKEN = true
    • CKA_CLASS = CKO_PRIVATE_KEY
  2. A search for all certificate objects on the token is performedby calling C_FindObjects[Init|Final]. The search template includesthe following attributes:
    • CKA_TOKEN = true
    • CKA_CLASS = CKO_CERTIFICATE
  3. Each private key object is matched with its correspondingcertificate by retrieving their respective CKA_ID attributes. Amatching pair must share the same unique CKA_ID.

    For each matching pair, the certificate chain is built byfollowing the issuer->subject path. From the end entitycertificate, a call to C_FindObjects[Init|Final] is made with asearch template that includes the following attributes:

    • CKA_TOKEN = true
    • CKA_CLASS = CKO_CERTIFICATE
    • CKA_SUBJECT = [DN of certificate issuer]

    This search is continued until either no certificate for theissuer is found, or until a self-signed certificate is found. Ifmore than one certificate is found the first one is used.

    Once a private key and certificate have been matched (and itscertificate chain built), the information is stored in a privatekey entry with the CKA_LABEL value from end entity certificate asthe KeyStore alias.

    If the end entity certificate has no CKA_LABEL, then the aliasis derived from the CKA_ID. If the CKA_ID can be determined toconsist exclusively of printable characters, then a String alias iscreated by decoding the CKA_ID bytes using the UTF-8 charset.Otherwise, a hex String alias is created from the CKA_ID bytes("0xFFFF...", for example).

    If multiple certificates share the same CKA_LABEL, then thealias is derived from the CKA_LABEL plus the end entity certificateissuer and serial number ("MyCert/CN=foobar/1234", forexample).

  4. Each certificate not part of a private key entry (as the endentity certificate) is checked whether it is trusted. If theCKA_TRUSTED attribute is true, then a KeyStore trusted certificateentry is created with the CKA_LABEL value as the KeyStore alias. Ifthe certificate has no CKA_LABEL, or if multiple certificates sharethe same CKA_LABEL, then the alias is derived as described above.

    If the CKA_TRUSTED attribute is not supported then no trustedcertificate entries are created.

  5. Any private key or certificate object not part of a private keyentry or trusted certificate entry is ignored.
  6. A search for all secret key objects on the token is performedby calling C_FindObjects[Init|Final]. The search template includesthe following attributes:
    • CKA_TOKEN = true
    • CKA_CLASS = CKO_SECRET_KEY

    A KeyStore secret key entry is created for each secret keyobject, with the CKA_LABEL value as the KeyStore alias. Each secretkey object must have a unique CKA_LABEL.

Write Access

To create new KeyStore entries on a PKCS#11 token to KeyStoreentries, the Sun PKCS#11 Provider's KeyStore implementationperforms the following operations.

  1. When creating a KeyStore entry (during KeyStore.setEntry, forexample), C_CreateObject is called with CKA_TOKEN=true to createtoken objects for the respective entry contents.

    Private key objects are stored with CKA_PRIVATE=true. TheKeyStore alias (UTF8-encoded) is set as the CKA_ID for both theprivate key and the corresponding end entity certificate. TheKeyStore alias is also set as the CKA_LABEL for the end entitycertificate object.

    Each certificate in a private key entry's chain is also stored.The CKA_LABEL is not set for CA certificates. If a CA certificateis already in the token, a duplicate is not stored.

    Secret key objects are stored with CKA_PRIVATE=true. TheKeyStore alias is set as the CKA_LABEL.

  2. If an attempt is made to convert a session object to a tokenobject (for example, if KeyStore.setEntry is called and the privatekey object in the specified entry is a session object), thenC_CopyObject is called with CKA_TOKEN=true.
  3. If multiple certificates in the token are found to share thesame CKA_LABEL, then the write capabilities to the token aredisabled.
  4. Since the PKCS#11 specification does not allow regularapplications to set CKA_TRUSTED=true (only token initializationapplications may do so), trusted certificate entries can not becreated.

Miscellaneous

In addition to the searches listed above, the following searchesmay be used by the Sun PKCS#11 provider's KeyStore implementationto perform internal functions. Specifically,C_FindObjects[Init|Final] may be called with any of the followingattribute templates:

Appendix C: Example Provider

package com.foo;import java.io.*;import java.lang.reflect.*;import java.security.*;import javax.crypto.*;/** * Example provider that demonstrates some of the new API features. * *  . implement multiple different algorithms in a single class. *    Previously each algorithm needed to be implemented in a separate class *    (e.g. one for SHA-256, one for SHA-384, etc.) * *  . multiple concurrent instances of the provider frontend class each *    associated with a different backend. * *  . it uses "unextractable" keys and lets the framework know which key *    objects it can and cannot support * * Note that this is only a simple example provider designed to demonstrate * several of the new features.  It is not explicitly designed for efficiency. */public final class ExampleProvider extends Provider {    // reference to the crypto backend that implements all the algorithms    final CryptoBackend cryptoBackend;    public ExampleProvider(String name, CryptoBackend cryptoBackend) {        super(name, 1.0, "JCA/JCE provider for " + name);        this.cryptoBackend = cryptoBackend;        // register the algorithms we support (SHA-256, SHA-384, DESede, and AES)        putService(new MyService            (this, "MessageDigest", "SHA-256", "com.foo.ExampleProvider$MyMessageDigest"));        putService(new MyService            (this, "MessageDigest", "SHA-384", "com.foo.ExampleProvider$MyMessageDigest"));        putService(new MyCipherService            (this, "Cipher", "DES", "com.foo.ExampleProvider$MyCipher"));        putService(new MyCipherService            (this, "Cipher", "AES", "com.foo.ExampleProvider$MyCipher"));    }    // the API of our fictitious crypto backend    static abstract class CryptoBackend {        abstract byte[] digest(String algorithm, byte[] data);        abstract byte[] encrypt(String algorithm, KeyHandle key, byte[] data);        abstract byte[] decrypt(String algorithm, KeyHandle key, byte[] data);        abstract KeyHandle createKey(String algorithm, byte[] keyData);    }    // the shell of the representation the crypto backend uses for keys    private static final class KeyHandle {        // fill in code    }    // we have our own ServiceDescription implementation that overrides newInstance()    // that calls the (Provider, String) constructor instead of the no-args constructor    private static class MyService extends Service {        private static final Class[] paramTypes = {Provider.class, String.class};        MyService(Provider provider, String type, String algorithm,                String className) {            super(provider, type, algorithm, className, null, null);        }        public Object newInstance(Object param) throws NoSuchAlgorithmException {            try {                // get the Class object for the implementation class                Class clazz;                Provider provider = getProvider();                ClassLoader loader = provider.getClass().getClassLoader();                if (loader == null) {                    clazz = Class.forName(getClassName());                } else {                    clazz = loader.loadClass(getClassName());                }                // fetch the (Provider, String) constructor                Constructor cons = clazz.getConstructor(paramTypes);                // invoke constructor and return the SPI object                Object obj = cons.newInstance(new Object[] {provider, getAlgorithm()});                return obj;            } catch (Exception e) {                throw new NoSuchAlgorithmException("Could not instantiate service", e);            }        }    }    // custom ServiceDescription class for Cipher objects. See supportsParameter() below    private static class MyCipherService extends MyService {        MyCipherService(Provider provider, String type, String algorithm,                String className) {            super(provider, type, algorithm, className);        }        // we override supportsParameter() to let the framework know which        // keys we can support. We support instances of MySecretKey, if they        // are stored in our provider backend, plus SecretKeys with a RAW encoding.        public boolean supportsParameter(Object obj) {            if (obj instanceof SecretKey == false) {                return false;            }            SecretKey key = (SecretKey)obj;            if (key.getAlgorithm().equals(getAlgorithm()) == false) {                return false;            }            if (key instanceof MySecretKey) {                MySecretKey myKey = (MySecretKey)key;                return myKey.provider == getProvider();            } else {                return "RAW".equals(key.getFormat());            }        }    }    // our generic MessageDigest implementation. It implements all digest    // algorithms in a single class. We only implement the bare minimum    // of MessageDigestSpi methods    private static final class MyMessageDigest extends MessageDigestSpi {        private final ExampleProvider provider;        private final String algorithm;        private ByteArrayOutputStream buffer;        MyMessageDigest(Provider provider, String algorithm) {            super();            this.provider = (ExampleProvider)provider;            this.algorithm = algorithm;            engineReset();        }        protected void engineReset() {            buffer = new ByteArrayOutputStream();        }        protected void engineUpdate(byte b) {            buffer.write(b);        }        protected void engineUpdate(byte[] b, int ofs, int len) {            buffer.write(b, ofs, len);        }        protected byte[] engineDigest() {            byte[] data = buffer.toByteArray();            byte[] digest = provider.cryptoBackend.digest(algorithm, data);            engineReset();            return digest;        }    }    // our generic Cipher implementation, only partially complete. It implements    // all cipher algorithms in a single class. We implement only as many of the    // CipherSpi methods as required to show how it could work    private static abstract class MyCipher extends CipherSpi {        private final ExampleProvider provider;        private final String algorithm;        private int opmode;        private MySecretKey myKey;        private ByteArrayOutputStream buffer;        MyCipher(Provider provider, String algorithm) {            super();            this.provider = (ExampleProvider)provider;            this.algorithm = algorithm;        }        protected void engineInit(int opmode, Key key, SecureRandom random)                throws InvalidKeyException {            this.opmode = opmode;            myKey = MySecretKey.getKey(provider, algorithm, key);            if (myKey == null) {                throw new InvalidKeyException();            }            buffer = new ByteArrayOutputStream();        }        protected byte[] engineUpdate(byte[] b, int ofs, int len) {            buffer.write(b, ofs, len);            return new byte[0];        }        protected int engineUpdate(byte[] b, int ofs, int len, byte[] out, int outOfs) {            buffer.write(b, ofs, len);            return 0;        }        protected byte[] engineDoFinal(byte[] b, int ofs, int len) {            buffer.write(b, ofs, len);            byte[] in = buffer.toByteArray();            byte[] out;            if (opmode == Cipher.ENCRYPT_MODE) {                out = provider.cryptoBackend.encrypt(algorithm, myKey.handle, in);            } else {                out = provider.cryptoBackend.decrypt(algorithm, myKey.handle, in);            }            buffer = new ByteArrayOutputStream();            return out;        }        // code for remaining CipherSpi methods goes here    }    // our SecretKey implementation. All our keys are stored in our crypto    // backend, we only have an opaque handle available. There is no    // encoded form of these keys.    private static final class MySecretKey implements SecretKey {        final String algorithm;        final Provider provider;        final KeyHandle handle;        MySecretKey(Provider provider, String algorithm, KeyHandle handle) {            super();            this.provider = provider;            this.algorithm = algorithm;            this.handle = handle;        }        public String getAlgorithm() {            return algorithm;        }        public String getFormat() {            return null; // this key has no encoded form        }        public byte[] getEncoded() {            return null; // this key has no encoded form        }        // Convert the given key to a key of the specified provider, if possible        static MySecretKey getKey(ExampleProvider provider, String algorithm, Key key) {            if (key instanceof SecretKey == false) {                return null;            }            // algorithm name must match            if (!key.getAlgorithm().equals(algorithm)) {                return null;            }            // if key is already an instance of MySecretKey and is stored            // on this provider, return it right away            if (key instanceof MySecretKey) {                MySecretKey myKey = (MySecretKey)key;                if (myKey.provider == provider) {                    return myKey;                }            }            // otherwise, if the input key has a RAW encoding, convert it            if (!"RAW".equals(key.getFormat())) {                return null;            }            byte[] encoded = key.getEncoded();            KeyHandle handle = provider.cryptoBackend.createKey(algorithm, encoded);            return new MySecretKey(provider, algorithm, handle);        }    }}

Copyright © 1993, 2020, Oracleand/or its affiliates. All rights reserved.
Contact Us

[8]ページ先頭

©2009-2025 Movatter.jp