Skip to content

Commit 4f8f54a

Browse files
committed
refactor Algorithm to accept both keys
1 parent 2bf84e0 commit 4f8f54a

File tree

6 files changed

+579
-153
lines changed

6 files changed

+579
-153
lines changed

lib/src/main/java/com/auth0/jwt/algorithms/Algorithm.java

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import com.auth0.jwt.exceptions.SignatureVerificationException;
55

66
import java.io.UnsupportedEncodingException;
7-
import java.security.interfaces.ECKey;
8-
import java.security.interfaces.RSAKey;
7+
import java.security.PrivateKey;
8+
import java.security.PublicKey;
9+
import java.security.interfaces.*;
910

1011
/**
1112
* The Algorithm class represents an algorithm to be used in the Signing or Verification process of a Token.
1213
*/
14+
@SuppressWarnings("WeakerAccess")
1315
public abstract class Algorithm {
1416

1517
private final String name;
@@ -21,9 +23,13 @@ public abstract class Algorithm {
2123
* @param key the key to use in the verify or signing instance.
2224
* @return a valid RSA256 Algorithm.
2325
* @throws IllegalArgumentException if the provided Key is null.
26+
* @deprecated use {@link #RSA256(RSAPublicKey, RSAPrivateKey)}
2427
*/
28+
@Deprecated
2529
public static Algorithm RSA256(RSAKey key) throws IllegalArgumentException {
26-
return new RSAAlgorithm("RS256", "SHA256withRSA", key);
30+
RSAPublicKey publicKey = key instanceof PublicKey ? (RSAPublicKey) key : null;
31+
RSAPrivateKey privateKey = key instanceof PrivateKey ? (RSAPrivateKey) key : null;
32+
return RSA256(publicKey, privateKey);
2733
}
2834

2935
/**
@@ -32,9 +38,13 @@ public static Algorithm RSA256(RSAKey key) throws IllegalArgumentException {
3238
* @param key the key to use in the verify or signing instance.
3339
* @return a valid RSA384 Algorithm.
3440
* @throws IllegalArgumentException if the provided Key is null.
41+
* @deprecated use {@link #RSA384(RSAPublicKey, RSAPrivateKey)}
3542
*/
43+
@Deprecated
3644
public static Algorithm RSA384(RSAKey key) throws IllegalArgumentException {
37-
return new RSAAlgorithm("RS384", "SHA384withRSA", key);
45+
RSAPublicKey publicKey = key instanceof PublicKey ? (RSAPublicKey) key : null;
46+
RSAPrivateKey privateKey = key instanceof PrivateKey ? (RSAPrivateKey) key : null;
47+
return RSA384(publicKey, privateKey);
3848
}
3949

4050
/**
@@ -43,9 +53,49 @@ public static Algorithm RSA384(RSAKey key) throws IllegalArgumentException {
4353
* @param key the key to use in the verify or signing instance.
4454
* @return a valid RSA512 Algorithm.
4555
* @throws IllegalArgumentException if the provided Key is null.
56+
* @deprecated use {@link #RSA512(RSAPublicKey, RSAPrivateKey)}
4657
*/
58+
@Deprecated
4759
public static Algorithm RSA512(RSAKey key) throws IllegalArgumentException {
48-
return new RSAAlgorithm("RS512", "SHA512withRSA", key);
60+
RSAPublicKey publicKey = key instanceof PublicKey ? (RSAPublicKey) key : null;
61+
RSAPrivateKey privateKey = key instanceof PrivateKey ? (RSAPrivateKey) key : null;
62+
return RSA512(publicKey, privateKey);
63+
}
64+
65+
/**
66+
* Creates a new Algorithm instance using SHA256withRSA. Tokens specify this as "RS256".
67+
*
68+
* @param publicKey the key to use in the verify instance.
69+
* @param privateKey the key to use in the signing instance.
70+
* @return a valid RSA256 Algorithm.
71+
* @throws IllegalArgumentException if both provided Keys are null.
72+
*/
73+
public static Algorithm RSA256(RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException {
74+
return new RSAAlgorithm("RS256", "SHA256withRSA", publicKey, privateKey);
75+
}
76+
77+
/**
78+
* Creates a new Algorithm instance using SHA384withRSA. Tokens specify this as "RS384".
79+
*
80+
* @param publicKey the key to use in the verify instance.
81+
* @param privateKey the key to use in the signing instance.
82+
* @return a valid RSA384 Algorithm.
83+
* @throws IllegalArgumentException if both provided Keys are null.
84+
*/
85+
public static Algorithm RSA384(RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException {
86+
return new RSAAlgorithm("RS384", "SHA384withRSA", publicKey, privateKey);
87+
}
88+
89+
/**
90+
* Creates a new Algorithm instance using SHA512withRSA. Tokens specify this as "RS512".
91+
*
92+
* @param publicKey the key to use in the verify instance.
93+
* @param privateKey the key to use in the signing instance.
94+
* @return a valid RSA512 Algorithm.
95+
* @throws IllegalArgumentException if both provided Keys are null.
96+
*/
97+
public static Algorithm RSA512(RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException {
98+
return new RSAAlgorithm("RS512", "SHA512withRSA", publicKey, privateKey);
4999
}
50100

51101
/**
@@ -123,9 +173,13 @@ public static Algorithm HMAC512(byte[] secret) throws IllegalArgumentException {
123173
* @param key the key to use in the verify or signing instance.
124174
* @return a valid ECDSA256 Algorithm.
125175
* @throws IllegalArgumentException if the provided Key is null.
176+
* @deprecated use {@link #ECDSA256(ECPublicKey, ECPrivateKey)}
126177
*/
178+
@Deprecated
127179
public static Algorithm ECDSA256(ECKey key) throws IllegalArgumentException {
128-
return new ECDSAAlgorithm("ES256", "SHA256withECDSA", 32, key);
180+
ECPublicKey publicKey = key instanceof PublicKey ? (ECPublicKey) key : null;
181+
ECPrivateKey privateKey = key instanceof PrivateKey ? (ECPrivateKey) key : null;
182+
return ECDSA256(publicKey, privateKey);
129183
}
130184

131185
/**
@@ -134,9 +188,13 @@ public static Algorithm ECDSA256(ECKey key) throws IllegalArgumentException {
134188
* @param key the key to use in the verify or signing instance.
135189
* @return a valid ECDSA384 Algorithm.
136190
* @throws IllegalArgumentException if the provided Key is null.
191+
* @deprecated use {@link #ECDSA384(ECPublicKey, ECPrivateKey)}
137192
*/
193+
@Deprecated
138194
public static Algorithm ECDSA384(ECKey key) throws IllegalArgumentException {
139-
return new ECDSAAlgorithm("ES384", "SHA384withECDSA", 48, key);
195+
ECPublicKey publicKey = key instanceof PublicKey ? (ECPublicKey) key : null;
196+
ECPrivateKey privateKey = key instanceof PrivateKey ? (ECPrivateKey) key : null;
197+
return ECDSA384(publicKey, privateKey);
140198
}
141199

142200
/**
@@ -145,9 +203,49 @@ public static Algorithm ECDSA384(ECKey key) throws IllegalArgumentException {
145203
* @param key the key to use in the verify or signing instance.
146204
* @return a valid ECDSA512 Algorithm.
147205
* @throws IllegalArgumentException if the provided Key is null.
206+
* @deprecated use {@link #ECDSA512(ECPublicKey, ECPrivateKey)}
148207
*/
208+
@Deprecated
149209
public static Algorithm ECDSA512(ECKey key) throws IllegalArgumentException {
150-
return new ECDSAAlgorithm("ES512", "SHA512withECDSA", 66, key);
210+
ECPublicKey publicKey = key instanceof PublicKey ? (ECPublicKey) key : null;
211+
ECPrivateKey privateKey = key instanceof PrivateKey ? (ECPrivateKey) key : null;
212+
return ECDSA512(publicKey, privateKey);
213+
}
214+
215+
/**
216+
* Creates a new Algorithm instance using SHA256withECDSA. Tokens specify this as "ES256".
217+
*
218+
* @param publicKey the key to use in the verify instance.
219+
* @param privateKey the key to use in the signing instance.
220+
* @return a valid ECDSA256 Algorithm.
221+
* @throws IllegalArgumentException if the provided Key is null.
222+
*/
223+
public static Algorithm ECDSA256(ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException {
224+
return new ECDSAAlgorithm("ES256", "SHA256withECDSA", 32, publicKey, privateKey);
225+
}
226+
227+
/**
228+
* Creates a new Algorithm instance using SHA384withECDSA. Tokens specify this as "ES384".
229+
*
230+
* @param publicKey the key to use in the verify instance.
231+
* @param privateKey the key to use in the signing instance.
232+
* @return a valid ECDSA384 Algorithm.
233+
* @throws IllegalArgumentException if the provided Key is null.
234+
*/
235+
public static Algorithm ECDSA384(ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException {
236+
return new ECDSAAlgorithm("ES384", "SHA384withECDSA", 48, publicKey, privateKey);
237+
}
238+
239+
/**
240+
* Creates a new Algorithm instance using SHA512withECDSA. Tokens specify this as "ES512".
241+
*
242+
* @param publicKey the key to use in the verify instance.
243+
* @param privateKey the key to use in the signing instance.
244+
* @return a valid ECDSA512 Algorithm.
245+
* @throws IllegalArgumentException if the provided Key is null.
246+
*/
247+
public static Algorithm ECDSA512(ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException {
248+
return new ECDSAAlgorithm("ES512", "SHA512withECDSA", 66, publicKey, privateKey);
151249
}
152250

153251
public static Algorithm none() {

lib/src/main/java/com/auth0/jwt/algorithms/ECDSAAlgorithm.java

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,51 @@
55

66
import java.security.InvalidKeyException;
77
import java.security.NoSuchAlgorithmException;
8-
import java.security.PrivateKey;
98
import java.security.SignatureException;
10-
import java.security.interfaces.ECKey;
119
import java.security.interfaces.ECPrivateKey;
1210
import java.security.interfaces.ECPublicKey;
1311

1412
class ECDSAAlgorithm extends Algorithm {
1513

14+
private final ECPublicKey publicKey;
15+
private final ECPrivateKey privateKey;
1616
private final CryptoHelper crypto;
1717
private final int ecNumberSize;
18-
private final ECKey key;
1918

20-
ECDSAAlgorithm(CryptoHelper crypto, String id, String algorithm, int ecNumberSize, ECKey key) throws IllegalArgumentException {
19+
//Visible for testing
20+
ECDSAAlgorithm(CryptoHelper crypto, String id, String algorithm, int ecNumberSize, ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException {
2121
super(id, algorithm);
22-
if (key == null) {
23-
throw new IllegalArgumentException("The ECKey cannot be null");
22+
if (publicKey == null && privateKey == null) {
23+
throw new IllegalArgumentException("Both provided Keys cannot be null.");
2424
}
25+
this.publicKey = publicKey;
26+
this.privateKey = privateKey;
2527
this.ecNumberSize = ecNumberSize;
26-
this.key = key;
2728
this.crypto = crypto;
2829
}
2930

30-
ECDSAAlgorithm(String id, String algorithm, int ecNumberSize, ECKey key) throws IllegalArgumentException {
31-
this(new CryptoHelper(), id, algorithm, ecNumberSize, key);
31+
ECDSAAlgorithm(String id, String algorithm, int ecNumberSize, ECPublicKey publicKey, ECPrivateKey privateKey) throws IllegalArgumentException {
32+
this(new CryptoHelper(), id, algorithm, ecNumberSize, publicKey, privateKey);
3233
}
3334

34-
ECKey getKey() {
35-
return key;
35+
ECPublicKey getPublicKey() {
36+
return publicKey;
37+
}
38+
39+
ECPrivateKey getPrivateKey() {
40+
return privateKey;
3641
}
3742

3843
@Override
3944
public void verify(byte[] contentBytes, byte[] signatureBytes) throws SignatureVerificationException {
4045
try {
41-
if (!(key instanceof ECPublicKey)) {
42-
throw new IllegalArgumentException("The given ECKey is not an ECPublicKey.");
46+
if (publicKey == null) {
47+
throw new IllegalArgumentException("The given Public Key is null.");
4348
}
4449
if (!isDERSignature(signatureBytes)) {
4550
signatureBytes = JOSEToDER(signatureBytes);
4651
}
47-
boolean valid = crypto.verifySignatureFor(getDescription(), (ECPublicKey) key, contentBytes, signatureBytes);
52+
boolean valid = crypto.verifySignatureFor(getDescription(), publicKey, contentBytes, signatureBytes);
4853

4954
if (!valid) {
5055
throw new SignatureVerificationException(this);
@@ -57,10 +62,10 @@ public void verify(byte[] contentBytes, byte[] signatureBytes) throws SignatureV
5762
@Override
5863
public byte[] sign(byte[] contentBytes) throws SignatureGenerationException {
5964
try {
60-
if (!(key instanceof ECPrivateKey)) {
61-
throw new IllegalArgumentException("The given ECKey is not a ECPrivateKey.");
65+
if (privateKey == null) {
66+
throw new IllegalArgumentException("The given Private Key is null.");
6267
}
63-
return crypto.createSignatureFor(getDescription(), (PrivateKey) key, contentBytes);
68+
return crypto.createSignatureFor(getDescription(), privateKey, contentBytes);
6469
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException | IllegalArgumentException e) {
6570
throw new SignatureGenerationException(this, e);
6671
}

lib/src/main/java/com/auth0/jwt/algorithms/RSAAlgorithm.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,48 @@
33
import com.auth0.jwt.exceptions.SignatureGenerationException;
44
import com.auth0.jwt.exceptions.SignatureVerificationException;
55

6-
import java.security.*;
7-
import java.security.interfaces.RSAKey;
6+
import java.security.InvalidKeyException;
7+
import java.security.NoSuchAlgorithmException;
8+
import java.security.SignatureException;
89
import java.security.interfaces.RSAPrivateKey;
910
import java.security.interfaces.RSAPublicKey;
1011

1112
class RSAAlgorithm extends Algorithm {
1213

13-
private final RSAKey key;
14+
private final RSAPublicKey publicKey;
15+
private final RSAPrivateKey privateKey;
1416
private final CryptoHelper crypto;
1517

16-
RSAAlgorithm(CryptoHelper crypto, String id, String algorithm, RSAKey key) throws IllegalArgumentException {
18+
//Visible for testing
19+
RSAAlgorithm(CryptoHelper crypto, String id, String algorithm, RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException {
1720
super(id, algorithm);
18-
if (key == null) {
19-
throw new IllegalArgumentException("The RSAKey cannot be null");
21+
if (publicKey == null && privateKey == null) {
22+
throw new IllegalArgumentException("Both provided Keys cannot be null.");
2023
}
21-
this.key = key;
24+
this.publicKey = publicKey;
25+
this.privateKey = privateKey;
2226
this.crypto = crypto;
2327
}
2428

25-
RSAAlgorithm(String id, String algorithm, RSAKey key) throws IllegalArgumentException {
26-
this(new CryptoHelper(), id, algorithm, key);
29+
RSAAlgorithm(String id, String algorithm, RSAPublicKey publicKey, RSAPrivateKey privateKey) throws IllegalArgumentException {
30+
this(new CryptoHelper(), id, algorithm, publicKey, privateKey);
2731
}
2832

29-
RSAKey getKey() {
30-
return key;
33+
RSAPublicKey getPublicKey() {
34+
return publicKey;
35+
}
36+
37+
RSAPrivateKey getPrivateKey() {
38+
return privateKey;
3139
}
3240

3341
@Override
3442
public void verify(byte[] contentBytes, byte[] signatureBytes) throws SignatureVerificationException {
3543
try {
36-
if (!(key instanceof PublicKey)) {
37-
throw new IllegalArgumentException("The given RSAKey is not a RSAPublicKey.");
44+
if (publicKey == null) {
45+
throw new IllegalArgumentException("The given Public Key is null.");
3846
}
39-
boolean valid = crypto.verifySignatureFor(getDescription(), (RSAPublicKey) key, contentBytes, signatureBytes);
47+
boolean valid = crypto.verifySignatureFor(getDescription(), publicKey, contentBytes, signatureBytes);
4048
if (!valid) {
4149
throw new SignatureVerificationException(this);
4250
}
@@ -48,10 +56,10 @@ public void verify(byte[] contentBytes, byte[] signatureBytes) throws SignatureV
4856
@Override
4957
public byte[] sign(byte[] contentBytes) throws SignatureGenerationException {
5058
try {
51-
if (!(key instanceof PrivateKey)) {
52-
throw new IllegalArgumentException("The given RSAKey is not a RSAPrivateKey.");
59+
if (privateKey == null) {
60+
throw new IllegalArgumentException("The given Private Key is null.");
5361
}
54-
return crypto.createSignatureFor(getDescription(), (RSAPrivateKey) key, contentBytes);
62+
return crypto.createSignatureFor(getDescription(), privateKey, contentBytes);
5563
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException | IllegalArgumentException e) {
5664
throw new SignatureGenerationException(this, e);
5765
}

0 commit comments

Comments
 (0)