1. /*
  2. * @(#)KeyFactory.java 1.20 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.security;
  8. import java.security.spec.KeySpec;
  9. import java.security.spec.InvalidKeySpecException;
  10. /**
  11. * Key factories are used to convert <I>keys</I> (opaque
  12. * cryptographic keys of type <code>Key</code>) into <I>key specifications</I>
  13. * (transparent representations of the underlying key material), and vice
  14. * versa.
  15. *
  16. * <P> Key factories are bi-directional. That is, they allow you to build an
  17. * opaque key object from a given key specification (key material), or to
  18. * retrieve the underlying key material of a key object in a suitable format.
  19. *
  20. * <P> Multiple compatible key specifications may exist for the same key.
  21. * For example, a DSA public key may be specified using
  22. * <code>DSAPublicKeySpec</code> or
  23. * <code>X509EncodedKeySpec</code>. A key factory can be used to translate
  24. * between compatible key specifications.
  25. *
  26. * <P> The following is an example of how to use a key factory in order to
  27. * instantiate a DSA public key from its encoding.
  28. * Assume Alice has received a digital signature from Bob.
  29. * Bob also sent her his public key (in encoded format) to verify
  30. * his signature. Alice then performs the following actions:
  31. *
  32. * <pre>
  33. * X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
  34. * KeyFactory keyFactory = KeyFactory.getInstance("DSA");
  35. * PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
  36. * Signature sig = Signature.getInstance("DSA");
  37. * sig.initVerify(bobPubKey);
  38. * sig.update(data);
  39. * sig.verify(signature);
  40. * </pre>
  41. *
  42. * @author Jan Luehe
  43. *
  44. * @version 1.20 01/11/29
  45. *
  46. * @see Key
  47. * @see PublicKey
  48. * @see PrivateKey
  49. * @see java.security.spec.KeySpec
  50. * @see java.security.spec.DSAPublicKeySpec
  51. * @see java.security.spec.X509EncodedKeySpec
  52. *
  53. * @since JDK1.2
  54. */
  55. public class KeyFactory {
  56. // The algorithm associated with this key factory
  57. private String algorithm;
  58. // The provider
  59. private Provider provider;
  60. // The provider implementation (delegate)
  61. private KeyFactorySpi keyFacSpi;
  62. /**
  63. * Creates a KeyFactory object.
  64. *
  65. * @param keyFacSpi the delegate
  66. * @param provider the provider
  67. */
  68. protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider,
  69. String algorithm) {
  70. this.keyFacSpi = keyFacSpi;
  71. this.provider = provider;
  72. this.algorithm = algorithm;
  73. }
  74. /**
  75. * Generates a KeyFactory object that implements the specified digest
  76. * algorithm. If the default provider package
  77. * provides an implementation of the requested digest algorithm,
  78. * an instance of KeyFactory containing that implementation is returned.
  79. * If the algorithm is not available in the default
  80. * package, other packages are searched.
  81. *
  82. * @param algorithm the name of the requested key algorithm.
  83. * See Appendix A in the <a href=
  84. * "../../../guide/security/CryptoSpec.html#AppA">
  85. * Java Cryptography Architecture API Specification & Reference </a>
  86. * for information about standard algorithm names.
  87. *
  88. * @return a KeyFactory object for the specified algorithm.
  89. *
  90. * @exception NoSuchAlgorithmException if the requested algorithm is
  91. * not available in the default provider package or any of the other
  92. * provider packages that were searched.
  93. */
  94. public static KeyFactory getInstance(String algorithm)
  95. throws NoSuchAlgorithmException {
  96. try {
  97. Object[] objs = Security.getImpl(algorithm, "KeyFactory",
  98. null);
  99. return new KeyFactory((KeyFactorySpi)objs[0],
  100. (Provider)objs[1],
  101. algorithm);
  102. } catch(NoSuchProviderException e) {
  103. throw new NoSuchAlgorithmException(algorithm + " not found");
  104. }
  105. }
  106. /**
  107. * Generates a KeyFactory object for the specified algorithm from the
  108. * specified provider.
  109. *
  110. * @param algorithm the name of the requested key algorithm.
  111. * See Appendix A in the <a href=
  112. * "../../../guide/security/CryptoSpec.html#AppA">
  113. * Java Cryptography Architecture API Specification & Reference </a>
  114. * for information about standard algorithm names.
  115. *
  116. * @param provider the name of the provider.
  117. *
  118. * @return a KeyFactory object for the specified algorithm.
  119. *
  120. * @exception NoSuchAlgorithmException if the algorithm is
  121. * not available from the specified provider.
  122. *
  123. * @exception NoSuchProviderException if the provider has not been
  124. * configured.
  125. *
  126. * @see Provider
  127. */
  128. public static KeyFactory getInstance(String algorithm, String provider)
  129. throws NoSuchAlgorithmException, NoSuchProviderException
  130. {
  131. if (provider == null || provider.length() == 0)
  132. throw new IllegalArgumentException("missing provider");
  133. Object[] objs = Security.getImpl(algorithm, "KeyFactory", provider);
  134. return new KeyFactory((KeyFactorySpi)objs[0], (Provider)objs[1],
  135. algorithm);
  136. }
  137. /**
  138. * Returns the provider of this key factory object.
  139. *
  140. * @return the provider of this key factory object
  141. */
  142. public final Provider getProvider() {
  143. return this.provider;
  144. }
  145. /**
  146. * Returns the name of the algorithm associated with this key factory.
  147. */
  148. public final String getAlgorithm() {
  149. return this.algorithm;
  150. }
  151. /**
  152. * Generates a public key object from the provided key specification
  153. * (key material).
  154. *
  155. * @param keySpec the specification (key material) of the public key.
  156. *
  157. * @return the public key.
  158. *
  159. * @exception InvalidKeySpecException if the given key specification
  160. * is inappropriate for this key factory to produce a public key.
  161. */
  162. public final PublicKey generatePublic(KeySpec keySpec)
  163. throws InvalidKeySpecException {
  164. return keyFacSpi.engineGeneratePublic(keySpec);
  165. }
  166. /**
  167. * Generates a private key object from the provided key specification
  168. * (key material).
  169. *
  170. * @param keySpec the specification (key material) of the private key.
  171. *
  172. * @return the private key.
  173. *
  174. * @exception InvalidKeySpecException if the given key specification
  175. * is inappropriate for this key factory to produce a private key.
  176. */
  177. public final PrivateKey generatePrivate(KeySpec keySpec)
  178. throws InvalidKeySpecException {
  179. return keyFacSpi.engineGeneratePrivate(keySpec);
  180. }
  181. /**
  182. * Returns a specification (key material) of the given key object.
  183. * <code>keySpec</code> identifies the specification class in which
  184. * the key material should be returned. It could, for example, be
  185. * <code>DSAPublicKeySpec.class</code>, to indicate that the
  186. * key material should be returned in an instance of the
  187. * <code>DSAPublicKeySpec</code> class.
  188. *
  189. * @param key the key.
  190. *
  191. * @param keySpec the specification class in which
  192. * the key material should be returned.
  193. *
  194. * @return the underlying key specification (key material) in an instance
  195. * of the requested specification class.
  196. *
  197. * @exception InvalidKeySpecException if the requested key specification is
  198. * inappropriate for the given key, or the given key cannot be processed
  199. * (e.g., the given key has an unrecognized algorithm or format).
  200. */
  201. public final KeySpec getKeySpec(Key key, Class keySpec)
  202. throws InvalidKeySpecException {
  203. return keyFacSpi.engineGetKeySpec(key, keySpec);
  204. }
  205. /**
  206. * Translates a key object, whose provider may be unknown or potentially
  207. * untrusted, into a corresponding key object of this key factory.
  208. *
  209. * @param key the key whose provider is unknown or untrusted.
  210. *
  211. * @return the translated key.
  212. *
  213. * @exception InvalidKeyException if the given key cannot be processed
  214. * by this key factory.
  215. */
  216. public final Key translateKey(Key key) throws InvalidKeyException {
  217. return keyFacSpi.engineTranslateKey(key);
  218. }
  219. }