/** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.security;import java.util.*;import java.security.Provider.Service;import java.security.spec.KeySpec;import java.security.spec.InvalidKeySpecException;import sun.security.util.Debug;import sun.security.jca.*;import sun.security.jca.GetInstance.Instance;/*** Key factories are used to convert <I>keys</I> (opaque* cryptographic keys of type {@code Key}) into <I>key specifications</I>* (transparent representations of the underlying key material), and vice* versa.** <P> Key factories are bi-directional. That is, they allow you to build an* opaque key object from a given key specification (key material), or to* retrieve the underlying key material of a key object in a suitable format.** <P> Multiple compatible key specifications may exist for the same key.* For example, a DSA public key may be specified using* {@code DSAPublicKeySpec} or* {@code X509EncodedKeySpec}. A key factory can be used to translate* between compatible key specifications.** <P> The following is an example of how to use a key factory in order to* instantiate a DSA public key from its encoding.* Assume Alice has received a digital signature from Bob.* Bob also sent her his public key (in encoded format) to verify* his signature. Alice then performs the following actions:** <pre>* X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);* KeyFactory keyFactory = KeyFactory.getInstance("DSA");* PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);* Signature sig = Signature.getInstance("DSA");* sig.initVerify(bobPubKey);* sig.update(data);* sig.verify(signature);* </pre>** <p> Every implementation of the Java platform is required to support the* following standard {@code KeyFactory} algorithms:* <ul>* <li>{@code DiffieHellman}</li>* <li>{@code DSA}</li>* <li>{@code RSA}</li>* </ul>* These algorithms are described in the <a href=* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">* KeyFactory section</a> of the* Java Security Standard Algorithm Names Specification.* Consult the release documentation for your implementation to see if any* other algorithms are supported.** @author Jan Luehe** @see Key* @see PublicKey* @see PrivateKey* @see java.security.spec.KeySpec* @see java.security.spec.DSAPublicKeySpec* @see java.security.spec.X509EncodedKeySpec** @since 1.2*/public class KeyFactory {private static final Debug debug =Debug.getInstance("jca", "KeyFactory");// The algorithm associated with this key factoryprivate final String algorithm;// The providerprivate Provider provider;// The provider implementation (delegate)private volatile KeyFactorySpi spi;// lock for mutex during provider selectionprivate final Object lock = new Object();// remaining services to try in provider selection// null once provider is selectedprivate Iterator<Service> serviceIterator;/*** Creates a KeyFactory object.** @param keyFacSpi the delegate* @param provider the provider* @param algorithm the name of the algorithm* to associate with this {@code KeyFactory}*/protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider,String algorithm) {this.spi = keyFacSpi;this.provider = provider;this.algorithm = algorithm;}private KeyFactory(String algorithm) throws NoSuchAlgorithmException {this.algorithm = algorithm;List<Service> list = GetInstance.getServices("KeyFactory", algorithm);serviceIterator = list.iterator();// fetch and instantiate initial spiif (nextSpi(null) == null) {throw new NoSuchAlgorithmException(algorithm + " KeyFactory not available");}}/*** Returns a KeyFactory object that converts* public/private keys of the specified algorithm.** <p> This method traverses the list of registered security Providers,* starting with the most preferred Provider.* A new KeyFactory object encapsulating the* KeyFactorySpi implementation from the first* Provider that supports the specified algorithm is returned.** <p> Note that the list of registered providers may be retrieved via* the {@link Security#getProviders() Security.getProviders()} method.** @implNote* The JDK Reference Implementation additionally uses the* {@code jdk.security.provider.preferred}* {@link Security#getProperty(String) Security} property to determine* the preferred provider order for the specified algorithm. This* may be different than the order of providers returned by* {@link Security#getProviders() Security.getProviders()}.** @param algorithm the name of the requested key algorithm.* See the KeyFactory section in the <a href=* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">* Java Security Standard Algorithm Names Specification</a>* for information about standard algorithm names.** @return the new {@code KeyFactory} object** @throws NoSuchAlgorithmException if no {@code Provider} supports a* {@code KeyFactorySpi} implementation for the* specified algorithm** @throws NullPointerException if {@code algorithm} is {@code null}** @see Provider*/public static KeyFactory getInstance(String algorithm)throws NoSuchAlgorithmException {Objects.requireNonNull(algorithm, "null algorithm name");return new KeyFactory(algorithm);}/*** Returns a KeyFactory object that converts* public/private keys of the specified algorithm.** <p> A new KeyFactory object encapsulating the* KeyFactorySpi implementation from the specified provider* is returned. The specified provider must be registered* in the security provider list.** <p> Note that the list of registered providers may be retrieved via* the {@link Security#getProviders() Security.getProviders()} method.** @param algorithm the name of the requested key algorithm.* See the KeyFactory section in the <a href=* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">* Java Security Standard Algorithm Names Specification</a>* for information about standard algorithm names.** @param provider the name of the provider.** @return the new {@code KeyFactory} object** @throws IllegalArgumentException if the provider name is {@code null}* or empty** @throws NoSuchAlgorithmException if a {@code KeyFactorySpi}* implementation for the specified algorithm is not* available from the specified provider** @throws NoSuchProviderException if the specified provider is not* registered in the security provider list** @throws NullPointerException if {@code algorithm} is {@code null}** @see Provider*/public static KeyFactory getInstance(String algorithm, String provider)throws NoSuchAlgorithmException, NoSuchProviderException {Objects.requireNonNull(algorithm, "null algorithm name");Instance instance = GetInstance.getInstance("KeyFactory",KeyFactorySpi.class, algorithm, provider);return new KeyFactory((KeyFactorySpi)instance.impl,instance.provider, algorithm);}/*** Returns a KeyFactory object that converts* public/private keys of the specified algorithm.** <p> A new KeyFactory object encapsulating the* KeyFactorySpi implementation from the specified Provider* object is returned. Note that the specified Provider object* does not have to be registered in the provider list.** @param algorithm the name of the requested key algorithm.* See the KeyFactory section in the <a href=* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">* Java Security Standard Algorithm Names Specification</a>* for information about standard algorithm names.** @param provider the provider.** @return the new {@code KeyFactory} object** @throws IllegalArgumentException if the specified provider is* {@code null}** @throws NoSuchAlgorithmException if a {@code KeyFactorySpi}* implementation for the specified algorithm is not available* from the specified {@code Provider} object** @throws NullPointerException if {@code algorithm} is {@code null}** @see Provider** @since 1.4*/public static KeyFactory getInstance(String algorithm, Provider provider)throws NoSuchAlgorithmException {Objects.requireNonNull(algorithm, "null algorithm name");Instance instance = GetInstance.getInstance("KeyFactory",KeyFactorySpi.class, algorithm, provider);return new KeyFactory((KeyFactorySpi)instance.impl,instance.provider, algorithm);}/*** Returns the provider of this key factory object.** @return the provider of this key factory object*/public final Provider getProvider() {synchronized (lock) {// disable further failover after this callserviceIterator = null;return provider;}}/*** Gets the name of the algorithm* associated with this {@code KeyFactory}.** @return the name of the algorithm associated with this* {@code KeyFactory}*/public final String getAlgorithm() {return this.algorithm;}/*** Update the active KeyFactorySpi of this class and return the next* implementation for failover. If no more implemenations are* available, this method returns null. However, the active spi of* this class is never set to null.*/private KeyFactorySpi nextSpi(KeyFactorySpi oldSpi) {synchronized (lock) {// somebody else did a failover concurrently// try that spi nowif ((oldSpi != null) && (oldSpi != spi)) {return spi;}if (serviceIterator == null) {return null;}while (serviceIterator.hasNext()) {Service s = serviceIterator.next();try {Object obj = s.newInstance(null);if (obj instanceof KeyFactorySpi == false) {continue;}KeyFactorySpi spi = (KeyFactorySpi)obj;provider = s.getProvider();this.spi = spi;return spi;} catch (NoSuchAlgorithmException e) {// ignore}}serviceIterator = null;return null;}}/*** Generates a public key object from the provided key specification* (key material).** @param keySpec the specification (key material) of the public key.** @return the public key.** @exception InvalidKeySpecException if the given key specification* is inappropriate for this key factory to produce a public key.*/public final PublicKey generatePublic(KeySpec keySpec)throws InvalidKeySpecException {if (serviceIterator == null) {return spi.engineGeneratePublic(keySpec);}Exception failure = null;KeyFactorySpi mySpi = spi;do {try {return mySpi.engineGeneratePublic(keySpec);} catch (Exception e) {if (failure == null) {failure = e;}mySpi = nextSpi(mySpi);}} while (mySpi != null);if (failure instanceof RuntimeException) {throw (RuntimeException)failure;}if (failure instanceof InvalidKeySpecException) {throw (InvalidKeySpecException)failure;}throw new InvalidKeySpecException("Could not generate public key", failure);}/*** Generates a private key object from the provided key specification* (key material).** @param keySpec the specification (key material) of the private key.** @return the private key.** @exception InvalidKeySpecException if the given key specification* is inappropriate for this key factory to produce a private key.*/public final PrivateKey generatePrivate(KeySpec keySpec)throws InvalidKeySpecException {if (serviceIterator == null) {return spi.engineGeneratePrivate(keySpec);}Exception failure = null;KeyFactorySpi mySpi = spi;do {try {return mySpi.engineGeneratePrivate(keySpec);} catch (Exception e) {if (failure == null) {failure = e;}mySpi = nextSpi(mySpi);}} while (mySpi != null);if (failure instanceof RuntimeException) {throw (RuntimeException)failure;}if (failure instanceof InvalidKeySpecException) {throw (InvalidKeySpecException)failure;}throw new InvalidKeySpecException("Could not generate private key", failure);}/*** Returns a specification (key material) of the given key object.* {@code keySpec} identifies the specification class in which* the key material should be returned. It could, for example, be* {@code DSAPublicKeySpec.class}, to indicate that the* key material should be returned in an instance of the* {@code DSAPublicKeySpec} class.** @param <T> the type of the key specification to be returned** @param key the key.** @param keySpec the specification class in which* the key material should be returned.** @return the underlying key specification (key material) in an instance* of the requested specification class.** @exception InvalidKeySpecException if the requested key specification is* inappropriate for the given key, or the given key cannot be processed* (e.g., the given key has an unrecognized algorithm or format).*/public final <T extends KeySpec> T getKeySpec(Key key, Class<T> keySpec)throws InvalidKeySpecException {if (serviceIterator == null) {return spi.engineGetKeySpec(key, keySpec);}Exception failure = null;KeyFactorySpi mySpi = spi;do {try {return mySpi.engineGetKeySpec(key, keySpec);} catch (Exception e) {if (failure == null) {failure = e;}mySpi = nextSpi(mySpi);}} while (mySpi != null);if (failure instanceof RuntimeException) {throw (RuntimeException)failure;}if (failure instanceof InvalidKeySpecException) {throw (InvalidKeySpecException)failure;}throw new InvalidKeySpecException("Could not get key spec", failure);}/*** Translates a key object, whose provider may be unknown or potentially* untrusted, into a corresponding key object of this key factory.** @param key the key whose provider is unknown or untrusted.** @return the translated key.** @exception InvalidKeyException if the given key cannot be processed* by this key factory.*/public final Key translateKey(Key key) throws InvalidKeyException {if (serviceIterator == null) {return spi.engineTranslateKey(key);}Exception failure = null;KeyFactorySpi mySpi = spi;do {try {return mySpi.engineTranslateKey(key);} catch (Exception e) {if (failure == null) {failure = e;}mySpi = nextSpi(mySpi);}} while (mySpi != null);if (failure instanceof RuntimeException) {throw (RuntimeException)failure;}if (failure instanceof InvalidKeyException) {throw (InvalidKeyException)failure;}throw new InvalidKeyException("Could not translate key", failure);}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。