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