1. /*
  2. * @(#)KeyFactory.java 1.28 02/05/07
  3. *
  4. * Copyright 2003 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.28, 05/07/02
  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 1.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. * @param algorithm the name of the algorithm
  68. * to associate with this <tt>KeyFactory</tt>
  69. */
  70. protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider,
  71. String algorithm) {
  72. this.keyFacSpi = keyFacSpi;
  73. this.provider = provider;
  74. this.algorithm = algorithm;
  75. }
  76. /**
  77. * Generates a KeyFactory object that implements the specified
  78. * algorithm. If the default provider package
  79. * provides an implementation of the requested algorithm,
  80. * an instance of KeyFactory containing that implementation is returned.
  81. * If the algorithm is not available in the default
  82. * package, other packages are searched.
  83. *
  84. * @param algorithm the name of the requested key algorithm.
  85. * See Appendix A in the <a href=
  86. * "../../../guide/security/CryptoSpec.html#AppA">
  87. * Java Cryptography Architecture API Specification & Reference </a>
  88. * for information about standard algorithm names.
  89. *
  90. * @return a KeyFactory object for the specified algorithm.
  91. *
  92. * @exception NoSuchAlgorithmException if the requested algorithm is
  93. * not available in the default provider package or any of the other
  94. * provider packages that were searched.
  95. */
  96. public static KeyFactory getInstance(String algorithm)
  97. throws NoSuchAlgorithmException {
  98. try {
  99. Object[] objs = Security.getImpl(algorithm, "KeyFactory",
  100. (String)null);
  101. return new KeyFactory((KeyFactorySpi)objs[0],
  102. (Provider)objs[1],
  103. algorithm);
  104. } catch(NoSuchProviderException e) {
  105. throw new NoSuchAlgorithmException(algorithm + " not found");
  106. }
  107. }
  108. /**
  109. * Generates a KeyFactory object for the specified algorithm from the
  110. * specified provider.
  111. *
  112. * @param algorithm the name of the requested key algorithm.
  113. * See Appendix A in the <a href=
  114. * "../../../guide/security/CryptoSpec.html#AppA">
  115. * Java Cryptography Architecture API Specification & Reference </a>
  116. * for information about standard algorithm names.
  117. *
  118. * @param provider the name of the provider.
  119. *
  120. * @return a KeyFactory object for the specified algorithm.
  121. *
  122. * @exception NoSuchAlgorithmException if the algorithm is
  123. * not available from the specified provider.
  124. *
  125. * @exception NoSuchProviderException if the provider has not been
  126. * configured.
  127. *
  128. * @exception IllegalArgumentException if the provider name is null
  129. * or empty.
  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. * Generates a KeyFactory object for the specified algorithm from the
  144. * specified provider. Note: the <code>provider</code> doesn't have
  145. * to be registered.
  146. *
  147. * @param algorithm the name of the requested key algorithm.
  148. * See Appendix A in the <a href=
  149. * "../../../guide/security/CryptoSpec.html#AppA">
  150. * Java Cryptography Architecture API Specification & Reference </a>
  151. * for information about standard algorithm names.
  152. *
  153. * @param provider the provider.
  154. *
  155. * @return a KeyFactory object for the specified algorithm.
  156. *
  157. * @exception NoSuchAlgorithmException if the algorithm is
  158. * not available from the specified provider.
  159. *
  160. * @exception IllegalArgumentException if the <code>provider</code> is
  161. * null.
  162. *
  163. * @see Provider
  164. *
  165. * @since 1.4
  166. */
  167. public static KeyFactory getInstance(String algorithm, Provider provider)
  168. throws NoSuchAlgorithmException
  169. {
  170. if (provider == null)
  171. throw new IllegalArgumentException("missing provider");
  172. Object[] objs = Security.getImpl(algorithm, "KeyFactory", provider);
  173. return new KeyFactory((KeyFactorySpi)objs[0], (Provider)objs[1],
  174. algorithm);
  175. }
  176. /**
  177. * Returns the provider of this key factory object.
  178. *
  179. * @return the provider of this key factory object
  180. */
  181. public final Provider getProvider() {
  182. return this.provider;
  183. }
  184. /**
  185. * Gets the name of the algorithm
  186. * associated with this <tt>KeyFactory</tt>.
  187. *
  188. * @return the name of the algorithm associated with this
  189. * <tt>KeyFactory</tt>
  190. */
  191. public final String getAlgorithm() {
  192. return this.algorithm;
  193. }
  194. /**
  195. * Generates a public key object from the provided key specification
  196. * (key material).
  197. *
  198. * @param keySpec the specification (key material) of the public key.
  199. *
  200. * @return the public key.
  201. *
  202. * @exception InvalidKeySpecException if the given key specification
  203. * is inappropriate for this key factory to produce a public key.
  204. */
  205. public final PublicKey generatePublic(KeySpec keySpec)
  206. throws InvalidKeySpecException {
  207. return keyFacSpi.engineGeneratePublic(keySpec);
  208. }
  209. /**
  210. * Generates a private key object from the provided key specification
  211. * (key material).
  212. *
  213. * @param keySpec the specification (key material) of the private key.
  214. *
  215. * @return the private key.
  216. *
  217. * @exception InvalidKeySpecException if the given key specification
  218. * is inappropriate for this key factory to produce a private key.
  219. */
  220. public final PrivateKey generatePrivate(KeySpec keySpec)
  221. throws InvalidKeySpecException {
  222. return keyFacSpi.engineGeneratePrivate(keySpec);
  223. }
  224. /**
  225. * Returns a specification (key material) of the given key object.
  226. * <code>keySpec</code> identifies the specification class in which
  227. * the key material should be returned. It could, for example, be
  228. * <code>DSAPublicKeySpec.class</code>, to indicate that the
  229. * key material should be returned in an instance of the
  230. * <code>DSAPublicKeySpec</code> class.
  231. *
  232. * @param key the key.
  233. *
  234. * @param keySpec the specification class in which
  235. * the key material should be returned.
  236. *
  237. * @return the underlying key specification (key material) in an instance
  238. * of the requested specification class.
  239. *
  240. * @exception InvalidKeySpecException if the requested key specification is
  241. * inappropriate for the given key, or the given key cannot be processed
  242. * (e.g., the given key has an unrecognized algorithm or format).
  243. */
  244. public final KeySpec getKeySpec(Key key, Class keySpec)
  245. throws InvalidKeySpecException {
  246. return keyFacSpi.engineGetKeySpec(key, keySpec);
  247. }
  248. /**
  249. * Translates a key object, whose provider may be unknown or potentially
  250. * untrusted, into a corresponding key object of this key factory.
  251. *
  252. * @param key the key whose provider is unknown or untrusted.
  253. *
  254. * @return the translated key.
  255. *
  256. * @exception InvalidKeyException if the given key cannot be processed
  257. * by this key factory.
  258. */
  259. public final Key translateKey(Key key) throws InvalidKeyException {
  260. return keyFacSpi.engineTranslateKey(key);
  261. }
  262. }