001 package com.nimbusds.jose.util;
002
003
004 import java.io.UnsupportedEncodingException;
005
006 import org.apache.commons.codec.binary.Base64;
007
008 import net.minidev.json.JSONAware;
009 import net.minidev.json.JSONValue;
010
011 import net.jcip.annotations.Immutable;
012
013
014 /**
015 * Base64URL-encoded object.
016 *
017 * <p>Related specifications:
018 *
019 * <ul>
020 * <li>RFC 4648.
021 * </ul>
022 *
023 * @author Vladimir Dzhuvinov
024 * @version $version$ (2013-01-15)
025 */
026 @Immutable
027 public class Base64URL implements JSONAware {
028
029
030 /**
031 * UTF-8 is the required charset for all JWTs.
032 */
033 private static final String CHARSET = "utf-8";
034
035
036 /**
037 * The Base64URL value.
038 */
039 private final String value;
040
041
042 /**
043 * Creates a new Base64URL-encoded object.
044 *
045 * @param base64URL The Base64URL-encoded object value. The value is not
046 * validated for having characters from a Base64URL
047 * alphabet. Must not be {@code null}.
048 */
049 public Base64URL(final String base64URL) {
050
051 if (base64URL == null)
052 throw new IllegalArgumentException("The Base64URL value must not be null");
053
054 value = base64URL;
055 }
056
057
058 /**
059 * Decodes this Base64URL object to a byte array.
060 *
061 * @return The resulting byte array.
062 */
063 public byte[] decode() {
064
065 return Base64.decodeBase64(value);
066 }
067
068
069 /**
070 * Decodes this Base64URL object to a string.
071 *
072 * @return The resulting string, in the UTF-8 character set.
073 */
074 public String decodeToString() {
075
076 try {
077 return new String(decode(), CHARSET);
078
079 } catch (UnsupportedEncodingException e) {
080
081 // UTF-8 should always be supported
082 return "";
083 }
084 }
085
086
087 /**
088 * Returns a JSON string representation of this object.
089 *
090 * @return The JSON string representation of this object.
091 */
092 public String toJSONString() {
093
094 return "\"" + JSONValue.escape(value) + "\"";
095 }
096
097
098 /**
099 * Returns a Base64URL string representation of this object.
100 *
101 * @return The Base64URL string representation.
102 */
103 public String toString() {
104
105 return value;
106 }
107
108
109 /**
110 * Overrides {@code Object.hashCode()}.
111 *
112 * @return The object hash code.
113 */
114 public int hashCode() {
115
116 return value.hashCode();
117 }
118
119
120 /**
121 * Overrides {@code Object.equals()}.
122 *
123 * @param object The object to compare to.
124 *
125 * @return {@code true} if the objects have the same value, otherwise
126 * {@code false}.
127 */
128 public boolean equals(final Object object) {
129
130 return object != null &&
131 object instanceof Base64URL &&
132 this.toString().equals(object.toString());
133 }
134
135
136 /**
137 * Base64URL-encode the specified string.
138 *
139 * @param text The string to encode. Must be in the UTF-8 character set
140 * and not {@code null}.
141 *
142 * @return The resulting Base64URL object.
143 */
144 public static Base64URL encode(final String text) {
145
146 try {
147 return encode(text.getBytes(CHARSET));
148
149 } catch (UnsupportedEncodingException e) {
150
151 // UTF-8 should always be supported
152 return null;
153 }
154 }
155
156
157 /**
158 * Base64URL-encode the specified byte array.
159 *
160 * @param bytes The byte array to encode. Must not be {@code null}.
161 *
162 * @return The resulting Base64URL object.
163 */
164 public static Base64URL encode(final byte[] bytes) {
165
166 return new Base64URL(Base64.encodeBase64URLSafeString(bytes));
167 }
168 }