2
* Copyright 2005-2012 Restlet S.A.S.
4
* The contents of this file are subject to the terms of one of the following
5
* open source licenses: Apache 2.0 or LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL
6
* 1.0 (the "Licenses"). You can select the license that you prefer but you may
7
* not use this file except in compliance with one of these Licenses.
9
* You can obtain a copy of the Apache 2.0 license at
10
* http://www.opensource.org/licenses/apache-2.0
12
* You can obtain a copy of the LGPL 3.0 license at
13
* http://www.opensource.org/licenses/lgpl-3.0
15
* You can obtain a copy of the LGPL 2.1 license at
16
* http://www.opensource.org/licenses/lgpl-2.1
18
* You can obtain a copy of the CDDL 1.0 license at
19
* http://www.opensource.org/licenses/cddl1
21
* You can obtain a copy of the EPL 1.0 license at
22
* http://www.opensource.org/licenses/eclipse-1.0
24
* See the Licenses for the specific language governing permissions and
25
* limitations under the Licenses.
27
* Alternatively, you can obtain a royalty free commercial license with less
28
* limitations, transferable or non-transferable, directly at
29
* http://www.restlet.com/products/restlet-framework
31
* Restlet is a registered trademark of Restlet S.A.S.
34
package org.restlet.ext.crypto.internal;
36
import java.security.GeneralSecurityException;
38
import javax.crypto.Cipher;
39
import javax.crypto.spec.SecretKeySpec;
41
import org.restlet.engine.util.Base64;
42
import org.restlet.ext.crypto.DigestUtils;
45
* Simple usage of standard cipher features from JRE.
47
* @author Remi Dewitte <remi@gide.net>
49
public final class CryptoUtils {
52
* Creates a cipher for a given algorithm and secret.
55
* The cryptographic algorithm.
57
* The cryptographic secret, encoded as a Base64 string.
59
* The cipher mode, either {@link Cipher#ENCRYPT_MODE} or
60
* {@link Cipher#DECRYPT_MODE}.
61
* @return The new cipher.
62
* @throws GeneralSecurityException
64
private static Cipher createCipher(String algo, String base64Secret,
65
int mode) throws GeneralSecurityException {
66
Cipher cipher = Cipher.getInstance(algo);
67
cipher.init(mode, new SecretKeySpec(Base64.decode(base64Secret), algo));
72
* Decrypts a bytes array.
75
* The cryptographic algorithm.
77
* The cryptographic secret, encoded as a Base64 string.
79
* The encrypted bytes.
80
* @return The decrypted content string.
81
* @throws GeneralSecurityException
83
public static String decrypt(String algo, String base64Secret,
84
byte[] encrypted) throws GeneralSecurityException {
85
byte[] original = doFinal(algo, base64Secret, Cipher.DECRYPT_MODE,
87
return new String(original);
91
* Does final processing.
94
* The cryptographic algorithm.
96
* The cryptographic secret, encoded as a Base64 string.
98
* The processing mode, either {@link Cipher#DECRYPT_MODE} or
99
* {@link Cipher#ENCRYPT_MODE}.
101
* The byte array to process.
102
* @return The processed byte array.
103
* @throws GeneralSecurityException
105
private static byte[] doFinal(String algo, String base64Secret, int mode,
106
byte[] what) throws GeneralSecurityException {
107
return createCipher(algo, base64Secret, mode).doFinal(what);
111
* Encrypts a content string.
114
* The cryptographic algorithm.
115
* @param base64Secret
116
* The cryptographic secret, encoded as a Base64 string.
118
* The content string to encrypt.
119
* @return The encrypted bytes.
120
* @throws GeneralSecurityException
122
public static byte[] encrypt(String algo, String base64Secret,
123
String content) throws GeneralSecurityException {
124
return doFinal(algo, base64Secret, Cipher.ENCRYPT_MODE, content
129
* Generates a nonce as recommended in section 3.2.1 of RFC-2617, but
130
* without the ETag field. The format is: <code><pre>
131
* Base64.encodeBytes(currentTimeMS + ":"
132
* + md5String(currentTimeMS + ":" + secretKey))
136
* a secret value known only to the creator of the nonce. It's
137
* inserted into the nonce, and can be used later to validate the
140
public static String makeNonce(String secretKey) {
141
final long currentTimeMS = System.currentTimeMillis();
142
return Base64.encode((currentTimeMS + ":" + DigestUtils
143
.toMd5(currentTimeMS + ":" + secretKey)).getBytes(), true);
147
* Private constructor to ensure that the class acts as a true utility class
148
* i.e. it isn't instantiable and extensible.
150
private CryptoUtils() {