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 }