an example using t he sun provider

Post on 08-Jan-2016

25 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

An example using t he SUN provider. The provider SUN is supplied i n J ava 2SDK . SUN provides both an implementation of the NIST Digital Signature Algorithm (DSA), and an implementation of the MD5 and NIST SHA-1 message digest algorithms. Class MessageDigest : - PowerPoint PPT Presentation

TRANSCRIPT

An example using the SUN provider The provider SUN is supplied in Java 2SDK. SUN provides both

an implementation of the NIST Digital Signature Algorithm (DSA), and an implementation of the MD5 and NIST SHA-1 message digest algorithms.

Class MessageDigest :looking at code that generates a message digest from a message.

MessageDigest messagedigest = MessageDigest. getInstance("SHA");MessageDigest messagedigest = MessageDigest.getInstance("SHA", "SUN");

getInstance() method can be used in two different way. The first requires only the algorithm to be specified.The second requires both the algorithm and the provider to be specified. Both return an instance of a class that implements the SHA algorithm.

Next, we pass the message through the message-digest generator.

int n = 0;   byte [ ] rgb = new byte [1000];   while ((n = inputstreamMessage.read(rgb)) > -1)   {       messagedigest.update(rgb, 0, n);    } This code works well for large messages of unknown length. The update() method also accepts a single byte as an argument for

messages of a few bytes in length, and a byte array for messages of a fixed or predictable size.  

 The final step involves generating the message digest itself.

rgb = messagedigest.digest();

The resulting digest is encoded in an array of bytes.

Message Digest Algorithm A message digest algorithm computes a

(typically shorter) fixed-size string from a message called the message digest (also known as a digital fingerprint).

Any change to the original message will result in a different message digest, providing a way to verify the integrity (that is, check the fingerprint) of the original message.

The message digest algorithm creates a message digest from a message.

The Complete Source Code for a program that

Generates a Message

import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.io.InputStream;import java.io.OutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;

Public class MessageDigestGenerator{ public void generateMessageDigest( InputStream inputstreamMessage, OutputStream outputstreamMessageDigest) throws NoSuchAlgorithmException, IOException { MessageDigest messagedigest = MessageDigest.getInstance("SHA"); int n = 0; byte [ ] rgb = new byte [1000]; while ((n = inputstreamMessage.read(rgb)) > -1) { messagedigest.update(rgb, 0, n); }

rgb = messagedigest.digest();

outputstreamMessageDigest.write(rgb); }

public static void main(String [] rgstring) { try { FileInputStream fileinputstream = new FileInputStream(rgstring[0]); FileOutputStream fileoutputstream = new FileOutputStream(rgstring[1]);

new MessageDigestGenerator(). generateMessageDigest (fileinputstream, fileoutputstream);

fileinputstream.close(); fileoutputstream.close(); } catch (Exception ex) { ex.printStackTrace(); } }}

Classes InputStream & OutputStream public abstract class InputStream extends Object

This abstract class is the superclass of all classes representing an input stream of bytes.

Applications that need to define a subclass of InputStream must always provide a method that returns the next byte of input.

public abstract class OutputStream extends ObjectThis abstract class is the superclass of all classes representing an

output stream of bytes. An output stream accepts output bytes and sends them to some

sink. Applications that need to define a subclass of OutputStream must

always provide at least a method that writes one byte of output.

InputStream class: read method detailed int read (byte[] b)

Reads some number of bytes from the input stream and stores them into the buffer array b.

The number of bytes actually read is returned as an integer. This method blocks until input data is available, end of file is

detected, or an exception is thrown. If b is null, a NullPointerException is thrown.If the length of b is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte. If no byte is available because the stream is at end of file, the value -

1 is returned; otherwise, at least one byte is read and stored into b.

Parameter: b - the buffer into which the data is read. Returns: the total number of bytes read into the buffer, or -1 is

there is no more data because the end of the stream has been reached.

Throws: IOException - if an I/O error occurs. NullPointerException- if b is null.

OutputStream class: write method detailed

void write (byte[] b) Writes b.length bytes from the specified byte array to this

output stream.The general contract for write(b) is that it should have exactly

the same effect as the call write(b, 0, b.length).

Parameters: b - the data. Throws: IOException if an I/O error occurs.

o Class IOExceptiono java.lang.Object

o java.lang.Throwableo java.lang.Exception java.io.IOException

Class FileInputStream

public class FileInputStream extends InputStream

A FileInputStream obtains input bytes from a file in a file system.

What files are available depends on the host environment.

FileInputStream is meant for reading streams of raw bytes such as image data.

For reading streams of characters, consider using FileReader.

FileInputStream Constructor public FileInputStream(String name) throws

FileNotFoundException

Creates a FileInputStream by opening a connection to an actual file, the file named by the path name name in the file system.

A new FileDescriptor object is created to represent this file connection.

First, if there is a security manager, its checkRead method is called with the name argument as its argument.

If the named file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading then a FileNotFoundException is thrown.

Class FileOutputStream

public class FileOutputStream extends OutputStream

A file output stream is an output stream for writing data to a File or to a FileDescriptor.

Whether or not a file is available or may be created depends upon the underlying platform.

Some platforms, in particular, allow a file to be opened for writing by only one FileOutputStream (or other file-writing object) at a time.

In such situations the constructors in this class will fail if the file involved is already open.

• FileOutputStream is meant for writing streams of raw bytes such as image data.

• For writing streams of characters, consider using FileWriter.

FileOutputStream Constructor public FileOutputStream(String name) throws FileNotFoundException

Creates an output file stream to write to the file with the specified name.

A new FileDescriptor object is created to represent this file connection. First, if there is a security manager, its checkWrite method is called

with name as its argument.

Parameters: name - the system-dependent filename Throws: FileNotFoundException if the file exists but is a directory rather than a regular file, if the file does not exist but cannot be created, or if the file cannot be opened for any other reason SecurityException if a security manager exists and its checkWrite method denies write

access to the file.

Key in Cryptographic Circles A key is a piece of information used to encrypt and/or decrypt

information There are two types of key-based cryptography:

secret-key and public-key. Secret-key cryptography uses a single key that both

encrypts and decrypts the information to be protected.Both the sender and the receiver must share the secret-

key. Secret-key cryptography is also known as symmetric

cryptography. Public-key cryptography uses two keys: a public key and a private key. One key decrypts information encrypted with the other. Only the private key must be protected. Public key cryptography is used for authentication.

Class KeyPairGenerator

To generate a digital signature (and encrypt data), we need keys.

Key generation, in its algorithm-independent form, is not substantially similar to creating and using a message digest.

KeyPairGenerator keypairgenerator = KeyPairGenerator.getInstance ("DSA");

this code creates an instance of a class that generates DSA-compatible keys.

A second (if necessary) argument specifies the provider.

After a key-pair generator instance is created, it must be initialized. We can initialize key-pair generators in one of two ways: algorithm-independent or algorithm-dependent.

Which method we use depends on the amount of control we want over the final result.

 keypairgenerator.initialize(1024, new SecureRandom());

Keys based on different algorithms differ in how they're generated, but they have one parameter in common -- the key's strength.

Strength is a relative term that corresponds roughly to how hard the key will be to "break."

If we use the algorithm-independent initializer, we can specify only the strength -- any algorithm-dependent values assume reasonable defaults.

  

DSAKeyPairGenerator dsakeypairgenerator = (DSAKeyPairGenerator)       keypairgenerator;   DSAParams dsaparams = new DSAParams()      {         private BigInteger p = BigInteger(...);         private BigInteger q = BigInteger(...);         private BigInteger g = BigInteger(...);         public BigInteger getP()         {            return p;         }         public BigInteger getQ()         {            return q;         }         public BigInteger getG()         {            return g;         }      };   dsakeypairgenerator.initialize(dsaparams, new SecureRandom());

While the defaults are usually good enough, if we need more control, it is available.

Let's assume we used the engine to create a generator of DSA-compatible keys, as in the code above.

The engine loaded and instantiated an instance of a class that implements the DSAKeyPairGenerator interface.

If we cast the generic key-pair generator we received to DSAKeyPairGenerator, we then gain access to the algorithm-dependent method of initialization.

To initialize a DSA key-pair generator, we need three values:

the prime P, the subprime Q, and the base G. These values are captured in an inner class instance that is

passed to the initialize() method. • The SecureRandom class provides a secure source of

random numbers used in the key-pair generation.   return keypairgenerator.generateKeyPair(); The final step involves generating the key pair itself.

The Complete Source Code for a program that Generates a Key Pair.

import java.security.Key;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.io.File;import java.io.InputStream;import java.io.OutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.IOException;public class KeyTools { public static void writeToFile(Key key, File file) throws IOException { FileOutputStream fileoutputstream = new FileOutputStream(file); ObjectOutputStream objectoutputstream = new ObjectOutputStream(fileoutputstream);

objectoutputstream.writeObject(key); objectoutputstream.close(); }

public static Key readFromFile(File file) throws ClassNotFoundException, IOException { FileInputStream fileinputstream = new FileInputStream(file); ObjectInputStream objectinputstream = new ObjectInputStream (fileinputstream); Key key = (Key)objectinputstream.readObject(); objectinputstream.close(); return key; } public static void writeToStream(Key key, OutputStream outputstream)

throws IOException { new ObjectOutputStream (outputstream) .writeObject(key); } public static Key readFromStream (InputStream inputstream) throws ClassNotFoundException,IOException { return (Key) new ObjectInputStream (inputstream). readObject(); }

public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {KeyPairGenerator keypairgenerator = KeyPairGenerator.getInstance("DSA");keypairgenerator.initialize(1024, new SecureRandom()); return keypairgenerator.generateKeyPair(); } public static void main(String [] rgstring) { try { File filePublic = new File(rgstring[0]); File filePrivate = new File(rgstring[1]); KeyPair keypair = generateKeyPair(); writeToFile(keypair.getPublic(), filePublic); writeToFile(keypair.getPrivate(), filePrivate); } catch (Exception ex) { ex.printStackTrace(); } }}

Class ObjectOutputStream An ObjectOutputStream writes primitive data types and

graphs of Java objects to an OutputStream.

public class ObjectOutputStream extends OutputStream

For example to write an object that can be read by the example in ObjectInputStream:

FileOutputStream fos = new FileOutputStream("t.tmp"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeInt(12345); oos.writeObject ("Today"); oos.writeObject(new Date()); oos.close();

Only objects that support the java.io.Serializable interface can be written to streams.

The class of each serializable object is encoded including the class name and signature of the class, the values of the object's fields and arrays, and the closure of any other objects referenced from the initial objects.

The method writeObject is used to write an object to the stream.

Any object, including Strings and arrays, is written with writeObject.

Multiple objects or primitives can be written to the stream. The objects must be read back from the corresponding

ObjectInputstream with the same types and in the same order as they were written

Digital Signature

A digital signature is also generated from a message.

It differs from a message digest because the private key of the message generator is incorporated into the computation.

The result is a message that has been "signed" by the one who holds the private key.

The computation is carried out in such a way that anyone can use the message generator's public key to verify that the entity signed it.

A good digital signature algorithm guarantees that the digital signature can't be forged (assuming the private key is secret),

that the signature is good for only the message from which it was generated,

that the message cannot be changed without invalidating the signature

that the message's authenticity can be verified.

The digital signature algorithm creates a digital signature from a message and a private key.

Class Signature The creation and use of an instance of the Signature class is also similiar

to the two previous examples. The differences lie in how the instance is used either

to sign or to verify a message.

    Signature signature = Signature.getInstance ("DSA");

Firstly, we use the engine to get an instance of the appropriate type. What we do next depends on whether or not we are signing or

verifying a message.    signature.initSign (privatekey);

In order to sign a message, we must first initialize the signature instance with the private key of the entity that is signing the message.

   signature.initVerify(publickey);

In order to verify a message, we must initialize the signature instance with the public key of the entity that claims it signed the message.

   int n = 0;   byte [] rgb = new byte [1000];   while ((n = inputstreamMessage.read(rgb)) > -1)   {      signature.update(rgb, 0, n);   }

Next, regardless of whether or not we are signing or verifying, we must pass the message through the signature generator.

This process is similiar to the earlier example of generating a message digest.

The final step consists of generating the signature or verifying a signature. rgb = signature.sign();

If we are signing a message, the sign() method returns the signature.

   signature.verify (rgbSignature);

If we are verifying the signature previously generated from a message, we must use the verify() method.

It takes as a parameter the previously generated signature and determines whether or not it is still valid.

The Complete Source Code for a program that Signs a Message

import java.security.Signature;import java.security.PrivateKey;import java.security.NoSuchAlgorithmException;import java.security.InvalidKeyException;import java.security.SignatureException;import java.io.File;import java.io.InputStream;import java.io.FileInputStream;import java.io.IOException;public class Sign{ public static byte [ ] generateSignature (PrivateKey privatekey, InputStream inputstreamMessage) throws NoSuchAlgorithmException, nvalidKeyException, SignatureException,

IOException { Signature signature = Signature.getInstance("DSA"); signature.initSign (privatekey); int n = 0; byte [ ] rgb = new byte [1000]; while ((n = inputstreamMessage.read(rgb)) > -1) { signature.update (rgb, 0, n); } rgb = signature.sign(); return rgb; }

public static void main(String [] rgstring) { try { File filePrivate = new File(rgstring[0]); File fileMessage = new File(rgstring[1]); File fileSignature = new File(rgstring[2]); PrivateKey privatekey = (PrivateKey)KeyTools.readFromFile(filePrivate); FileInputStream fileinputstream = new FileInputStream(fileMessage); byte [] rgb = generateSignature(privatekey, fileinputstream); fileinputstream.close(); SignatureTools.writeToFile(rgb, fileSignature); } catch (Exception ex) { ex.printStackTrace(); } }}

The Complete Source Code for a program that Verifies a Message.

import java.security.Signature;import java.security.PublicKey;import java.security.NoSuchAlgorithmException;import java.security.InvalidKeyException;import java.security.SignatureException;import java.io.File;import java.io.InputStream;import java.io.IOException;import java.io.OutputStream;import java.io.FileInputStream;

import java.io.FileOutputStream;public class Verify{ public static boolean verifySignature (PublicKey publickey, Input Stream inputstreamMessage, byte [] rgbSignature) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException,IOException {Signature signature = Signature.getInstance("DSA"); signature.initVerify(publickey); int n = 0; byte [] rgb = new byte [1000]; while ((n = inputstreamMessage.read(rgb)) > -1) { signature.update(rgb, 0, n); } return signature.verify(rgbSignature); }

public static void main(String [] rgstring) { try { File filePublic = new File(rgstring[0]); File fileMessage = new File(rgstring[1]); File fileSignature = new File(rgstring[2]);

PublicKey publickey = (PublicKey)KeyTools.readFromFile(filePublic); FileInputStream fileinputstream = new FileInputStream(fileMessage); byte [] rgb = SignatureTools.readFromFile(fileSignature); if (verifySignature (publickey, fileinputstream, rgb)) { System.out.println ("true"); } else { System.out.println ("false"); } fileinputstream.close(); } catch (Exception ex) { ex.printStackTrace(); } } }

The JCA conveniently hides all the low-level implementation and algorithm-specific details, allowing you to work at a higher, more abstract level.

Of course, one of the risks of such an abstract approach is the increased likelihood that we won't recognize erroneous output resulting from bugs.

Given the role of cryptography, this can be a significant problem.

Consider the "off-by-one" bug in the update line below:

   int n = 0;   byte [] rgb = new byte [1000];   while ((n = inputstreamMessage.read(rgb)) > -1)   {      messagedigest.update(rgb, 0, n - 1);   }

SUN version 1.5    sun.security.provider.Sun SunRsaSign version 1.5   

 sun.security.rsa.SunRsaSign SunJSSE version 1.5

     com.sun.net.ssl.internal.ssl.Provider SunJCE version 1.5

 com.sun.crypto.provider.SunJCE SunJGSS version 1.0     

sun.security.jgss.SunProvider SunSASL version 1.5

com.sun.security.sasl.Provider SunDeploy-MSCrypto 1.5  version  

com.sun.deploy.security.MSCryptoProvider

package sun.security.provider; import java.io.*; import java.util.*; import java.security.*; public final class Sun extends Provider { private static final String INFO = "SUN " + "(DSA key/parameter generation;

DSA signing; " + "SHA-1, MD5 digests; SecureRandom; X.509 certificates; JKS keystore)";

public Sun() { /* We are the SUN provider */ super("SUN", 1.2, INFO); AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { /* * Signature engines */ put("Signature.SHA1withDSA", "sun.security.provider.DSA"); put("Alg.Alias.Signature.DSA", "SHA1withDSA"); put("Alg.Alias.Signature.DSS", "SHA1withDSA"); put("Alg.Alias. Signature. SHA/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA"); put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA"); put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA"); put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA"); put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA"); put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");

* Key Pair Generator engines */ put(“ KeyPairGenerator.DSA", "sun.security.provider.DSAKeyPairGenerator"); put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA"); put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA"); put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA"); /* * Digest engines */ put("MessageDigest.MD5", "sun.security.provider.MD5"); put( "MessageDigest.SHA", "sun.security.provider.SHA"); put("Alg.Alias.MessageDigest.SHA-1", "SHA"); put("Alg.Alias.MessageDigest.SHA1", "SHA"); /* * Algorithm Parameter Generator engines */ put ("AlgorithmParameterGenerator.DSA", "sun.security.provider.DSAParameterGenerator"); /* * Algorithm Parameter engines */ put("AlgorithmParameters.DSA", "sun.security.provider.DSAParameters"); put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA"); put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA"); /* * Key factories */ put(“ KeyFactory.DSA", "sun.security.provider.DSAKeyFactory"); put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");

/* * SecureRandom */ put("SecureRandom.SHA1PRNG", "sun.security.provider.SecureRandom");/* * Certificates */ put("CertificateFactory.X509", "sun.security.provider.X509Factory"); put("Alg.Alias.CertificateFactory.X.509", "X509"); /* * KeyStore */ put ("KeyStore. JKS", "sun.security.provider.JavaKeyStore"); /* * KeySize */ put("Signature.SHA1withDSA KeySize", "1024"); put("KeyPairGenerator.DSA KeySize", "1024"); put("AlgorithmParameterGenerator.DSA

KeySize", "1024"); /* * Implementation type: software or hardware */ put("Signature.SHA1withDSA ImplementedIn", "Software"); put("KeyPairGenerator.DSA ImplementedIn", "Software"); put("MessageDigest.MD5 ImplementedIn", "Software"); put("MessageDigest.SHA ImplementedIn", "Software"); put("AlgorithmParameterGenerator.DSA ImplementedIn", "Software"); put("AlgorithmParameters.DSA ImplementedIn", "Software"); put("KeyFactory.DSA ImplementedIn", "Software"); put("SecureRandom.SHA1PRNG ImplementedIn", "Software"); put("CertificateFactory.X509 ImplementedIn", "Software"); put(“ KeyStore.JKS ImplementedIn", "Software"); return null; } } )

Example: Java Security Providers

The following Java2 applet enumerates all the Java Security Providers available to the j2re and their associated properties and values.

These property values specify the engine.algorithms and the classes that implement them, as well as other properties.

The public method of the applet is accessed by a scripted call to the method from JavaScript.

The method returns the data in a formatted table string.

A JavaScript function embeds the table of results into a simple html page in another scripted window.

import java.io.*;import java.util.*;import java.awt.* ;import java.security.*;public class SecProviders extends java.applet.Applet { public void init() { } // end init() public String getSecurityProviders() { StringBuffer strbuff = new StringBuffer(10000) ; //typical size of buffer to hold html string output try { Provider p[] = Security.getProviders();

strbuff.append("<table border=1 cellpadding =3>"); for (int i = 0; i < p.length; i++) {strbuff.append("<tr><td bgcolor =blue colspan =2><font size=+1

color=yellow><b>" + p[i] + "&nbsp; &nbsp; &nbsp; &nbsp;" + p[i]. getClass(). getName() + "</b></font></tr>\r\n") ;

for (Enumeration e = p[i].keys(); e.hasMoreElements();) { String key = (String) e.nextElement() ;strbuff.append("<tr><td>" + key + "</td><td>" +

p[i].getProperty(key) + "</td></tr>\r\n") ;} } strbuff.append("</table>\r\n") ; return strbuff.toString(); } catch (Exception e) { return e.toString(); } } }

The subclasses of the Provider class

For each service implemented by the provider, there must be a property whose name is the type of service:

Signature.algName [one or more spaces] attrName MessageDigest.algName [one or more spaces] attrName KeyPairGenerator.algName [one/more spaces] attrName SecureRandom.algName [one /spaces] attrName KeyFactory.algName [one / spaces] attrName CertificateFactory.certType [one or more spaces] attrName KeyStore.storeType [one or more spaces] attrName AlgorithmParameterGenerator.algName [one / spaces]

attrName AlgorithmParameters.algName [one / more spaces]

attrName

Java Security Provider Examples The default provider "SUN" implements the SHA1withDSA

Digital Signature Algorithm in software. In the master class for the provider "SUN", it sets the

"Signature.SHA1withDSA ImplementedIn" to have the value "Software" via the following:

put ("Signature.SHA1withDSA ImplementedIn", "Software") The default provider "SUN" implements the Digital Signature

Algorithm (whose standard name is "SHA1withDSA") in a class named DSA in the sun.security.provider package.

• Its subclass of Provider sets the Signature.SHA1withDSA property to have the value "sun.security.provider.DSA" via the following:

put("Signature.SHA1withDSA", "sun.security.provider.DSA")

getProvidersmethod

public static Provider[ ] getProviders() Returns an array containing all the installed

providers. The order of the providers in the array is their preference order. Returns an array of all the installed providers.

getProvidermethod

public static Provider getProvider(String name) Returns the provider installed with the specified

name, if any. Returns null if no provider with the specified name

is installed.

Parameters: name - the name of the provider to get. Returns: he provider of the specified name.

get Providers method public static Provider [] getProviders (Map filter)

Returns an array containing all installed providers that satisfy the specified selection criteria, or

Returns null if no such providers have been installed. The returned providers are ordered according to their

preference order Parameters: filter - the criteria for selecting providers. The filter is case-

insensitive. Returns: all the installed providers that satisfy the selection criteria, or null if

no such providers have been installed. Throws: InvalidParameterException - if the filter is not in the required format

The selection criteria are represented by a map. Each map entry represents a selection criterion. A provider is selected iff it satisfies all selection criteria.

The key entry The key for any entry in such a map must be in one of the following two

formats: <crypto_service>.<algorithm_or_type> MessageDigest.SHA-384 , MessageDigest.MD5 ,

The cryptographic service name must not contain any dots. The value associated with the key must be an empty string. A provider satisfies this selection criterion iff the provider implements the

specified algorithm or type for the specified cryptographic service.

<crypto_service>.<algorithm_or_type> <attribute_name>Provider.id className , Provider.id version , KeyStore.JKS ImplementedIn ,MessageDigest.SHA ImplementedIn , KeyFactory.DSA ImplementedIn The cryptographic service name must not contain any dots. The value associated with the key must be a non-empty string. A provider satisfies this selection criterion iff the provider implements the

specified algorithm or type for the specified cryptographic service and its implementation meets the constraint expressed by the specified attribute name/value pair.

top related