PageRenderTime 70ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/shine/src/main/java/org/apache/shiro/crypto/CipherService.java

http://cng1985.googlecode.com/
Java | 175 lines | 10 code | 8 blank | 157 comment | 0 complexity | 6c2d9dcea1d3374a83fc4de3f53887c2 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.apache.shiro.crypto;
  20. import org.apache.shiro.util.ByteSource;
  21. import java.io.InputStream;
  22. import java.io.OutputStream;
  23. /**
  24. * A {@code CipherService} uses a cryptographic algorithm called a
  25. * <a href="http://en.wikipedia.org/wiki/Cipher">Cipher</a> to convert an original input source using a {@code key} to
  26. * an uninterpretable format. The resulting encrypted output is only able to be converted back to original form with
  27. * a {@code key} as well. {@code CipherService}s can perform both encryption and decryption.
  28. * <h2>Cipher Basics</h2>
  29. * For what is known as <em>Symmetric</em> {@code Cipher}s, the {@code Key} used to encrypt the source is the same
  30. * as (or trivially similar to) the {@code Key} used to decrypt it.
  31. * <p/>
  32. * For <em>Asymmetric</em> {@code Cipher}s, the encryption {@code Key} is not the same as the decryption {@code Key}.
  33. * The most common type of Asymmetric Ciphers are based on what is called public/private key pairs:
  34. * <p/>
  35. * A <em>private</em> key is known only to a single party, and as its name implies, is supposed be kept very private
  36. * and secure. A <em>public</em> key that is associated with the private key can be disseminated freely to anyone.
  37. * Then data encrypted by the public key can only be decrypted by the private key and vice versa, but neither party
  38. * need share their private key with anyone else. By not sharing a private key, you can guarantee no 3rd party can
  39. * intercept the key and therefore use it to decrypt a message.
  40. * <p/>
  41. * This asymmetric key technology was created as a
  42. * more secure alternative to symmetric ciphers that sometimes suffer from man-in-the-middle attacks since, for
  43. * data shared between two parties, the same Key must also be shared and may be compromised.
  44. * <p/>
  45. * Note that a symmetric cipher is perfectly fine to use if you just want to encode data in a format no one else
  46. * can understand and you never give away the key. Shiro uses a symmetric cipher when creating certain
  47. * HTTP Cookies for example - because it is often undesirable to have user's identity stored in a plain-text cookie,
  48. * that identity can be converted via a symmetric cipher. Since the the same exact Shiro application will receive
  49. * the cookie, it can decrypt it via the same {@code Key} and there is no potential for discovery since that Key
  50. * is never shared with anyone.
  51. * <h2>{@code CipherService}s vs JDK {@link javax.crypto.Cipher Cipher}s</h2>
  52. * Shiro {@code CipherService}s essentially do the same things as JDK {@link javax.crypto.Cipher Cipher}s, but in
  53. * simpler and easier-to-use ways for most application developers. When thinking about encrypting and decrypting data
  54. * in an application, most app developers want what a {@code CipherService} provides, rather than having to manage the
  55. * lower-level intricacies of the JDK's {@code Cipher} API. Here are a few reasons why most people prefer
  56. * {@code CipherService}s:
  57. * <ul>
  58. * <li><b>Stateless Methods</b> - {@code CipherService} method calls do not retain state between method invocations.
  59. * JDK {@code Cipher} instances do retain state across invocations, requiring its end-users to manage the instance
  60. * and its state themselves.</li>
  61. * <li><b>Thread Safety</b> - {@code CipherService} instances are thread-safe inherently because no state is
  62. * retained across method invocations. JDK {@code Cipher} instances retain state and cannot be used by multiple
  63. * threads concurrently.</li>
  64. * <li><b>Single Operation</b> - {@code CipherService} method calls are single operation methods: encryption or
  65. * decryption in their entirety are done as a single method call. This is ideal for the large majority of developer
  66. * needs where you have something unencrypted and just want it decrypted (or vice versa) in a single method call. In
  67. * contrast, JDK {@code Cipher} instances can support encrypting/decrypting data in chunks over time (because it
  68. * retains state), but this often introduces API clutter and confusion for most application developers.</li>
  69. * <li><b>Type Safe</b> - There are {@code CipherService} implementations for different Cipher algorithms
  70. * ({@code AesCipherService}, {@code BlowfishCipherService}, etc). There is only one JDK {@code Cipher} class to
  71. * represent all cipher algorithms/instances.
  72. * <li><b>Simple Construction</b> - Because {@code CipherService} instances are type-safe, instantiating and using
  73. * one is often as simple as calling the default constructor, for example, <code>new AesCipherService();</code>. The
  74. * JDK {@code Cipher} class however requires using a procedural factory method with String arguments to indicate how
  75. * the instance should be created. The String arguments themselves are somewhat cryptic and hard to
  76. * understand unless you're a security expert. Shiro hides these details from you, but allows you to configure them
  77. * if you want.</li>
  78. * </ul>
  79. *
  80. * @see BlowfishCipherService
  81. * @see AesCipherService
  82. * @since 1.0
  83. */
  84. public interface CipherService {
  85. /**
  86. * Decrypts encrypted data via the specified cipher key and returns the original (pre-encrypted) data.
  87. * Note that the key must be in a format understood by the CipherService implementation.
  88. *
  89. * @param encrypted the previously encrypted data to decrypt
  90. * @param decryptionKey the cipher key used during decryption.
  91. * @return a byte source representing the original form of the specified encrypted data.
  92. * @throws CryptoException if there is an error during decryption
  93. */
  94. ByteSource decrypt(byte[] encrypted, byte[] decryptionKey) throws CryptoException;
  95. /**
  96. * Receives encrypted data from the given {@code InputStream}, decrypts it, and sends the resulting decrypted data
  97. * to the given {@code OutputStream}.
  98. * <p/>
  99. * <b>NOTE:</b> This method <em>does NOT</em> flush or close either stream prior to returning - the caller must
  100. * do so when they are finished with the streams. For example:
  101. * <pre>
  102. * try {
  103. * InputStream in = ...
  104. * OutputStream out = ...
  105. * cipherService.decrypt(in, out, decryptionKey);
  106. * } finally {
  107. * if (in != null) {
  108. * try {
  109. * in.close();
  110. * } catch (IOException ioe1) { ... log, trigger event, etc }
  111. * }
  112. * if (out != null) {
  113. * try {
  114. * out.close();
  115. * } catch (IOException ioe2) { ... log, trigger event, etc }
  116. * }
  117. * }
  118. * </pre>
  119. *
  120. * @param in the stream supplying the data to decrypt
  121. * @param out the stream to send the decrypted data
  122. * @param decryptionKey the cipher key to use for decryption
  123. * @throws CryptoException if there is any problem during decryption.
  124. */
  125. void decrypt(InputStream in, OutputStream out, byte[] decryptionKey) throws CryptoException;
  126. /**
  127. * Encrypts data via the specified cipher key. Note that the key must be in a format understood by
  128. * the {@code CipherService} implementation.
  129. *
  130. * @param raw the data to encrypt
  131. * @param encryptionKey the cipher key used during encryption.
  132. * @return a byte source with the encrypted representation of the specified raw data.
  133. * @throws CryptoException if there is an error during encryption
  134. */
  135. ByteSource encrypt(byte[] raw, byte[] encryptionKey) throws CryptoException;
  136. /**
  137. * Receives the data from the given {@code InputStream}, encrypts it, and sends the resulting encrypted data to the
  138. * given {@code OutputStream}.
  139. * <p/>
  140. * <b>NOTE:</b> This method <em>does NOT</em> flush or close either stream prior to returning - the caller must
  141. * do so when they are finished with the streams. For example:
  142. * <pre>
  143. * try {
  144. * InputStream in = ...
  145. * OutputStream out = ...
  146. * cipherService.encrypt(in, out, encryptionKey);
  147. * } finally {
  148. * if (in != null) {
  149. * try {
  150. * in.close();
  151. * } catch (IOException ioe1) { ... log, trigger event, etc }
  152. * }
  153. * if (out != null) {
  154. * try {
  155. * out.close();
  156. * } catch (IOException ioe2) { ... log, trigger event, etc }
  157. * }
  158. * }
  159. * </pre>
  160. *
  161. * @param in the stream supplying the data to encrypt
  162. * @param out the stream to send the encrypted data
  163. * @param encryptionKey the cipher key to use for encryption
  164. * @throws CryptoException if there is any problem during encryption.
  165. */
  166. void encrypt(InputStream in, OutputStream out, byte[] encryptionKey) throws CryptoException;
  167. }