From 8998d2236907ca6e4e7a4124ab17ca05bc546e47 Mon Sep 17 00:00:00 2001 From: Justin Richer Date: Thu, 22 Dec 2011 13:15:56 -0500 Subject: [PATCH] added signature validator --- .../java/org/mitre/jwt/AbstractJwtSigner.java | 39 +++++++++++++++++-- .../java/org/mitre/jwt/Hmac256Signer.java | 19 ++++----- src/main/java/org/mitre/jwt/JwtSigner.java | 2 + .../java/org/mitre/jwt/PlaintextSigner.java | 9 ++--- src/test/java/org/mitre/jwt/JwtTest.java | 23 ++++++++++- 5 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/mitre/jwt/AbstractJwtSigner.java b/src/main/java/org/mitre/jwt/AbstractJwtSigner.java index aa17755ef..016211b7b 100644 --- a/src/main/java/org/mitre/jwt/AbstractJwtSigner.java +++ b/src/main/java/org/mitre/jwt/AbstractJwtSigner.java @@ -1,8 +1,13 @@ package org.mitre.jwt; -import com.google.common.base.Objects; +import java.util.List; -public class AbstractJwtSigner implements JwtSigner { +import com.google.common.base.Objects; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Lists; + +public abstract class AbstractJwtSigner implements JwtSigner { public static final String PLAINTEXT = "none"; public static final String HS256 = "HS256"; @@ -40,8 +45,36 @@ public class AbstractJwtSigner implements JwtSigner { // for now, we fix the Jwt jwt.getHeader().setAlgorithm(algorithm); } - + + String sig = generateSignature(jwt.getSignatureBase()); + + jwt.setSignature(sig); } + /* (non-Javadoc) + * @see org.mitre.jwt.JwtSigner#verify(java.lang.String) + */ + @Override + public boolean verify(String jwtString) { + // split on the dots + List parts = Lists.newArrayList(Splitter.on(".").split(jwtString)); + + if (parts.size() != 3) { + throw new IllegalArgumentException("Invalid JWT format."); + } + + String h64 = parts.get(0); + String c64 = parts.get(1); + String s64 = parts.get(2); + + String expectedSignature = generateSignature(h64 + "." + c64 + "."); + + return Strings.nullToEmpty(s64).equals(Strings.nullToEmpty(expectedSignature)); + + } + + + protected abstract String generateSignature(String signatureBase); + } \ No newline at end of file diff --git a/src/main/java/org/mitre/jwt/Hmac256Signer.java b/src/main/java/org/mitre/jwt/Hmac256Signer.java index e9d1ed2dd..81f98d8a7 100644 --- a/src/main/java/org/mitre/jwt/Hmac256Signer.java +++ b/src/main/java/org/mitre/jwt/Hmac256Signer.java @@ -34,15 +34,10 @@ public class Hmac256Signer extends AbstractJwtSigner { } - /* (non-Javadoc) - * @see org.mitre.jwt.AbstractJwtSigner#sign(org.mitre.jwt.Jwt) - */ - @Override - public void sign(Jwt jwt) { - super.sign(jwt); - + @Override + protected String generateSignature(String signatureBase) { if (passphrase == null) { - return; // TODO: probably throw some kind of exception + return null; // TODO: probably throw some kind of exception } try { @@ -53,7 +48,7 @@ public class Hmac256Signer extends AbstractJwtSigner { } try { - mac.update(jwt.getSignatureBase().getBytes("UTF-8")); + mac.update(signatureBase.getBytes("UTF-8")); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -68,8 +63,7 @@ public class Hmac256Signer extends AbstractJwtSigner { // strip off any padding sig = sig.replace("=", ""); - - jwt.setSignature(sig); + return sig; } /** @@ -85,7 +79,8 @@ public class Hmac256Signer extends AbstractJwtSigner { public void setPassphrase(byte[] passphrase) { this.passphrase = passphrase; } - + + } diff --git a/src/main/java/org/mitre/jwt/JwtSigner.java b/src/main/java/org/mitre/jwt/JwtSigner.java index 3d2f3c797..ffe7f8cb8 100644 --- a/src/main/java/org/mitre/jwt/JwtSigner.java +++ b/src/main/java/org/mitre/jwt/JwtSigner.java @@ -4,4 +4,6 @@ public interface JwtSigner { public void sign(Jwt jwt); + public boolean verify(String jwtString); + } diff --git a/src/main/java/org/mitre/jwt/PlaintextSigner.java b/src/main/java/org/mitre/jwt/PlaintextSigner.java index 8c1058b1a..5e197da7b 100644 --- a/src/main/java/org/mitre/jwt/PlaintextSigner.java +++ b/src/main/java/org/mitre/jwt/PlaintextSigner.java @@ -7,11 +7,8 @@ public class PlaintextSigner extends AbstractJwtSigner { } @Override - public void sign(Jwt jwt) { - super.sign(jwt); - - jwt.setSignature(""); - - } + protected String generateSignature(String signatureBase) { + return null; + } } diff --git a/src/test/java/org/mitre/jwt/JwtTest.java b/src/test/java/org/mitre/jwt/JwtTest.java index 5c09702f8..1fe9aa739 100644 --- a/src/test/java/org/mitre/jwt/JwtTest.java +++ b/src/test/java/org/mitre/jwt/JwtTest.java @@ -39,7 +39,7 @@ public class JwtTest { } @Test - public void testHmacSignature() { + public void testGenerateHmacSignature() { Jwt jwt = new Jwt(); jwt.getHeader().setType("JWT"); jwt.getHeader().setAlgorithm("HS256"); @@ -79,6 +79,27 @@ public class JwtTest { } + @Test + public void testValidateHmacSignature() { + // sign it + byte[] key = null; + try { + key = "secret".getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + JwtSigner signer = new Hmac256Signer(key); + + String jwtString = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.iGBPJj47S5q_HAhSoQqAdcS6A_1CFj3zrLaImqNbt9E"; + + boolean valid = signer.verify(jwtString); + + assertThat(valid, equalTo(Boolean.TRUE)); + + } + @Test public void testParse() { String source = "eyJhbGciOiJub25lIn0.eyJleHAiOjEzMDA4MTkzODAsImlzcyI6ImpvZSIsImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.";