Skip to content
This repository was archived by the owner on Apr 10, 2025. It is now read-only.

Commit e21f714

Browse files
authored
ECDSA support for JWT (#41)
1 parent c3814d7 commit e21f714

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

GeneXusJWT/src/main/java/com/genexus/JWT/utils/JWTAlgorithm.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import com.genexus.securityapicommons.keys.PrivateKeyManager;
77

88
public enum JWTAlgorithm {
9-
HS256, HS512, RS256, RS512,;
9+
HS256, HS512, RS256, RS512, ES256, ES384, ES512 ;
1010

1111
public static String valueOf(JWTAlgorithm jWTAlgorithm, Error error) {
1212
switch (jWTAlgorithm) {
@@ -18,6 +18,12 @@ public static String valueOf(JWTAlgorithm jWTAlgorithm, Error error) {
1818
return "RS256";
1919
case RS512:
2020
return "RS512";
21+
case ES256:
22+
return "ES256";
23+
case ES384:
24+
return "ES384";
25+
case ES512:
26+
return "ES512";
2127
default:
2228
error.setError("JA001", "Unrecognized algorithm");
2329
return "Unrecognized algorithm";
@@ -34,6 +40,12 @@ public static JWTAlgorithm getJWTAlgorithm(String jWTAlgorithm, Error error) {
3440
return JWTAlgorithm.RS256;
3541
case "RS512":
3642
return JWTAlgorithm.RS512;
43+
case "ES256":
44+
return JWTAlgorithm.ES256;
45+
case "ES384":
46+
return JWTAlgorithm.ES384;
47+
case "ES512":
48+
return JWTAlgorithm.ES512;
3749
default:
3850
error.setError("JA002", "Unrecognized algorithm");
3951
return null;
@@ -44,6 +56,9 @@ public static boolean isPrivate(JWTAlgorithm jWTAlgorithm) {
4456
switch (jWTAlgorithm) {
4557
case RS256:
4658
case RS512:
59+
case ES256:
60+
case ES384:
61+
case ES512:
4762
return true;
4863
default:
4964
return false;
@@ -88,6 +103,27 @@ public static Algorithm getAsymmetricAlgorithm(JWTAlgorithm algorithm, PrivateKe
88103
error.setError("JA008", e.getMessage());
89104
return null;
90105
}
106+
case ES256:
107+
try {
108+
return Algorithm.ECDSA256(cert.getECPublicKeyJWT(), key.getECPrivateKeyJWT());
109+
} catch (Exception e) {
110+
error.setError("JA008", e.getMessage());
111+
return null;
112+
}
113+
case ES384:
114+
try {
115+
return Algorithm.ECDSA384(cert.getECPublicKeyJWT(), key.getECPrivateKeyJWT());
116+
} catch (Exception e) {
117+
error.setError("JA008", e.getMessage());
118+
return null;
119+
}
120+
case ES512:
121+
try {
122+
return Algorithm.ECDSA512(cert.getECPublicKeyJWT(), key.getECPrivateKeyJWT());
123+
} catch (Exception e) {
124+
error.setError("JA008", e.getMessage());
125+
return null;
126+
}
91127
default:
92128
error.setError("JA006", "Unknown asymmetric algorithm");
93129
return null;

SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/CertificateX509.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.security.cert.Certificate;
1414
import java.security.cert.CertificateException;
1515
import java.security.cert.X509Certificate;
16+
import java.security.interfaces.ECPublicKey;
1617
import java.security.interfaces.RSAPublicKey;
1718
import java.security.spec.InvalidKeySpecException;
1819
import java.security.spec.X509EncodedKeySpec;
@@ -432,5 +433,32 @@ public String getPublicKeyAlgorithm() {
432433
String[] aux = this.publicKeyAlgorithm.split("with");
433434
return aux[1].toUpperCase();
434435
}
436+
437+
/**
438+
* @return ECPublicKey type for the key type
439+
*/
440+
public ECPublicKey getECPublicKeyJWT() {
441+
KeyFactory kf = null;
442+
X509EncodedKeySpec encodedKeySpec = null;
443+
try {
444+
kf = SecurityUtils.getKeyFactory(this.getPublicKeyAlgorithm());
445+
encodedKeySpec = new X509EncodedKeySpec(this.subjectPublicKeyInfo.getEncoded());
446+
447+
} catch (NoSuchAlgorithmException | IOException e) {
448+
this.error.setError("CE017", "Error reading algorithm");
449+
}
450+
ECPublicKey pk = null;
451+
if ((kf != null) && (encodedKeySpec != null)) {
452+
try {
453+
454+
pk = (ECPublicKey) kf.generatePublic(encodedKeySpec);
455+
} catch (InvalidKeySpecException e) {
456+
// e.printStackTrace();
457+
this.error.setError("CE018", "Error casting public key data for JWT signing");
458+
}
459+
}
460+
return pk;
461+
462+
}
435463

436464
}

SecurityAPICommons/src/main/java/com/genexus/securityapicommons/keys/PrivateKeyManager.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.security.PrivateKey;
1212
import java.security.UnrecoverableKeyException;
1313
import java.security.cert.CertificateException;
14+
import java.security.interfaces.ECPrivateKey;
1415
import java.security.interfaces.RSAPrivateKey;
1516
import java.security.spec.InvalidKeySpecException;
1617
import java.security.spec.PKCS8EncodedKeySpec;
@@ -397,5 +398,31 @@ private boolean loadPrivateKeyFromPEMFile(String path) throws IOException, Certi
397398
}
398399
return flag;
399400
}
401+
402+
/**
403+
* @return PublicKey type for the key type
404+
*/
405+
public ECPrivateKey getECPrivateKeyJWT() {
406+
407+
KeyFactory kf = null;
408+
PKCS8EncodedKeySpec keySpec = null;
409+
try {
410+
kf = SecurityUtils.getKeyFactory(this.getPrivateKeyAlgorithm());
411+
keySpec = new PKCS8EncodedKeySpec(this.privateKeyInfo.getEncoded());
412+
413+
} catch (NoSuchAlgorithmException | IOException e) {
414+
this.error.setError("PK019", "Error reading algorithm");
415+
}
416+
ECPrivateKey pk = null;
417+
if ((kf != null) && (keySpec != null)) {
418+
try {
419+
pk = (ECPrivateKey) kf.generatePrivate(keySpec);
420+
} catch (InvalidKeySpecException e) {
421+
this.error.setError("PK020", "Error reading key");
422+
}
423+
}
424+
return pk;
425+
426+
}
400427

401428
}

0 commit comments

Comments
 (0)