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