1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.forgerock.json.jose.jwe;
18
19 import java.security.Key;
20
21 import org.forgerock.json.jose.jwe.handlers.compression.CompressionHandler;
22 import org.forgerock.json.jose.jwe.handlers.encryption.EncryptionHandler;
23 import org.forgerock.json.jose.jws.SignedJwt;
24 import org.forgerock.json.jose.jwt.Jwt;
25 import org.forgerock.json.jose.jwt.JwtClaimsSet;
26 import org.forgerock.json.jose.jwt.JwtHeader;
27 import org.forgerock.json.jose.jwt.Payload;
28 import org.forgerock.json.jose.utils.Utils;
29 import org.forgerock.util.encode.Base64url;
30
31
32
33
34
35
36
37
38
39
40
41 public class EncryptedJwt implements Jwt, Payload {
42
43 private final EncryptionManager encryptionManager = new EncryptionManager();
44 private final CompressionManager compressionManager = new CompressionManager();
45
46 private final JweHeader header;
47
48 private Payload payload;
49 private final Key publicKey;
50
51 private final String encodedHeader;
52 private final byte[] encryptedContentEncryptionKey;
53 private final byte[] initialisationVector;
54 private final byte[] ciphertext;
55 private final byte[] authenticationTag;
56
57
58
59
60
61
62
63
64
65
66 public EncryptedJwt(JweHeader header, JwtClaimsSet payload, Key publicKey) {
67 this(header, (Payload) payload, publicKey);
68 }
69
70 EncryptedJwt(JweHeader header, Payload payload, Key encryptionKey) {
71 this.header = header;
72 this.payload = payload;
73 this.publicKey = encryptionKey;
74
75 this.encodedHeader = null;
76 this.encryptedContentEncryptionKey = null;
77 this.initialisationVector = null;
78 this.ciphertext = null;
79 this.authenticationTag = null;
80 }
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public EncryptedJwt(JweHeader header, String encodedHeader, byte[] encryptedContentEncryptionKey,
97 byte[] initialisationVector, byte[] ciphertext, byte[] authenticationTag) {
98 this.header = header;
99 this.encodedHeader = encodedHeader;
100 this.encryptedContentEncryptionKey = encryptedContentEncryptionKey;
101 this.initialisationVector = initialisationVector;
102 this.ciphertext = ciphertext;
103 this.authenticationTag = authenticationTag;
104
105 this.publicKey = null;
106 }
107
108 @Override
109 public JwtHeader getHeader() {
110 return header;
111 }
112
113 @Override
114 public JwtClaimsSet getClaimsSet() {
115 return (JwtClaimsSet) payload;
116 }
117
118
119
120
121
122
123 Payload getPayload() {
124 return payload;
125 }
126
127 @Override
128 public String build() {
129
130 EncryptionHandler encryptionHandler = encryptionManager.getEncryptionHandler(header);
131
132 Key contentEncryptionKey = encryptionHandler.getContentEncryptionKey();
133 if (contentEncryptionKey == null) {
134 contentEncryptionKey = publicKey;
135 }
136 byte[] encryptedContentEncryptionKey = encryptionHandler.generateJWEEncryptedKey(publicKey,
137 contentEncryptionKey);
138 String encodedEncryptedKey = Base64url.encode(encryptedContentEncryptionKey);
139
140
141 byte[] initialisationVector = encryptionHandler.generateInitialisationVector();
142 String encodedInitialisationVector = Base64url.encode(initialisationVector);
143
144
145 String jweHeader = header.build();
146 String encodedJweHeader = Utils.base64urlEncode(jweHeader);
147 byte[] plaintext = compressPlaintext(header.getCompressionAlgorithm(),
148 payload.build().getBytes(Utils.CHARSET));
149 byte[] additionalAuthenticatedData = encodedJweHeader.getBytes(Utils.CHARSET);
150 JweEncryption cipherTextAndAuthTag = encryptionHandler.encryptPlaintext(contentEncryptionKey,
151 initialisationVector, plaintext, additionalAuthenticatedData);
152
153 String encodedCiphertext = Base64url.encode(cipherTextAndAuthTag.getCiphertext());
154 String encodedAuthenticationTag = Base64url.encode(cipherTextAndAuthTag.getAuthenticationTag());
155
156
157 return new StringBuilder(encodedJweHeader)
158 .append(".").append(encodedEncryptedKey)
159 .append(".").append(encodedInitialisationVector)
160 .append(".").append(encodedCiphertext)
161 .append(".").append(encodedAuthenticationTag)
162 .toString();
163 }
164
165
166
167
168
169
170
171
172
173
174 private byte[] compressPlaintext(CompressionAlgorithm compressionAlgorithm, byte[] plaintext) {
175 CompressionHandler compressionHandler = compressionManager.getCompressionHandler(compressionAlgorithm);
176 return compressionHandler.compress(plaintext);
177 }
178
179
180
181
182
183
184
185
186 public void decrypt(Key privateKey) {
187
188 EncryptionHandler encryptionHandler = encryptionManager.getEncryptionHandler(header);
189
190 Key contentEncryptionKey = encryptionHandler.decryptContentEncryptionKey(privateKey,
191 encryptedContentEncryptionKey);
192
193 byte[] additionalAuthenticatedData = encodedHeader.getBytes(Utils.CHARSET);
194
195 byte[] plaintext = encryptionHandler.decryptCiphertext(contentEncryptionKey, initialisationVector, ciphertext,
196 authenticationTag, additionalAuthenticatedData);
197 plaintext = decompressPlaintext(header.getCompressionAlgorithm(), plaintext);
198
199 String decryptedPayload = new String(plaintext, Utils.CHARSET);
200
201 payload = decodePayload(decryptedPayload);
202 }
203
204
205
206
207
208
209
210
211
212 private byte[] decompressPlaintext(CompressionAlgorithm compressionAlgorithm, byte[] plaintext) {
213 CompressionHandler compressionHandler = compressionManager.getCompressionHandler(compressionAlgorithm);
214 return compressionHandler.decompress(plaintext);
215 }
216
217
218
219
220
221
222
223 Payload decodePayload(String decryptedPayload) {
224 return new JwtClaimsSet(Utils.parseJson(decryptedPayload));
225 }
226 }