You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/03/30 06:48:31 UTC
[1/2] directory-kerby git commit: DIRKRB-193 Token decryption.
Contributed by Jiajia
Repository: directory-kerby
Updated Branches:
refs/heads/master ff0200f8b -> 9f2fe83c1
DIRKRB-193 Token decryption. Contributed by Jiajia
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/d0f33b01
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/d0f33b01
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/d0f33b01
Branch: refs/heads/master
Commit: d0f33b011fd8851caf0193b5c119e5983fa09d52
Parents: ff0200f
Author: Drankye <dr...@gmail.com>
Authored: Mon Mar 30 20:42:46 2015 +0800
Committer: Drankye <dr...@gmail.com>
Committed: Mon Mar 30 20:42:46 2015 +0800
----------------------------------------------------------------------
.../provider/token/JwtTokenDecoder.java | 54 +++++++++++++++++++-
.../provider/token/JwtTokenEncoder.java | 42 +++++++++++++--
.../kerberos/provider/token/TokenTest.java | 36 +++++++++++++
3 files changed, 127 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/d0f33b01/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
index 97f0ec3..c915ae1 100644
--- a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
+++ b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
@@ -19,17 +19,24 @@
*/
package org.apache.kerby.kerberos.provider.token;
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.crypto.RSADecrypter;
+import com.nimbusds.jwt.EncryptedJWT;
+import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.JWTParser;
import com.nimbusds.jwt.PlainJWT;
import org.apache.kerby.kerberos.kerb.provider.TokenDecoder;
import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
import java.io.IOException;
+import java.security.interfaces.RSAPrivateKey;
import java.text.ParseException;
/**
* JWT token decoder, implemented using Nimbus JWT library.
*/
public class JwtTokenDecoder implements TokenDecoder {
+ private static RSAPrivateKey decryptionKey;
@Override
public AuthToken decodeFromBytes(byte[] content) throws IOException {
@@ -40,11 +47,54 @@ public class JwtTokenDecoder implements TokenDecoder {
@Override
public AuthToken decodeFromString(String content) throws IOException {
+ JWT jwt = null;
try {
- PlainJWT jwt = PlainJWT.parse(content);
- return new JwtAuthToken(jwt.getJWTClaimsSet());
+ jwt = JWTParser.parse(content);
} catch (ParseException e) {
+ // Invalid JWT encoding
throw new IOException("Failed to parse JWT token string", e);
}
+ // Check the JWT type
+ if (jwt instanceof PlainJWT) {
+ PlainJWT plainObject = (PlainJWT) jwt;
+ try {
+ return new JwtAuthToken(plainObject.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ } else if (jwt instanceof EncryptedJWT) {
+ EncryptedJWT encryptedJWT = (EncryptedJWT) jwt;
+ decryptEncryptedJWT(encryptedJWT);
+ try {
+ return new JwtAuthToken(encryptedJWT.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ } else {
+ throw new IOException("Unexpected JWT type: " + jwt);
+ }
+ }
+
+ /**
+ * Decrypt the Encrypted JWT
+ *
+ * @param encryptedJWT
+ */
+ public void decryptEncryptedJWT(EncryptedJWT encryptedJWT) throws IOException {
+ RSADecrypter decrypter = new RSADecrypter(decryptionKey);
+ try {
+ encryptedJWT.decrypt(decrypter);
+ } catch (JOSEException e) {
+ throw new IOException("Failed to decrypt the encrypted JWT", e);
+ }
+ }
+
+ /**
+ * Set the decryption key
+ *
+ * @param key a private key
+ */
+ public static void setDecryptionKey(RSAPrivateKey key) {
+ decryptionKey = key;
}
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/d0f33b01/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
index 80c3947..07b5c3e 100644
--- a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
+++ b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
@@ -19,19 +19,27 @@
*/
package org.apache.kerby.kerberos.provider.token;
+import com.nimbusds.jose.EncryptionMethod;
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWEAlgorithm;
+import com.nimbusds.jose.JWEHeader;
+import com.nimbusds.jose.crypto.RSAEncrypter;
+import com.nimbusds.jwt.EncryptedJWT;
import com.nimbusds.jwt.JWT;
-import com.nimbusds.jwt.PlainJWT;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
-import java.io.IOException;
+import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
/**
* JWT token encoder, implemented using Nimbus JWT library.
*/
public class JwtTokenEncoder implements TokenEncoder {
+ private static JWEAlgorithm jweAlgorithm = JWEAlgorithm.RSA_OAEP;
+ private static EncryptionMethod encryptionMethod = EncryptionMethod.A128GCM;
+ private static RSAPublicKey encryptionKey;
@Override
public byte[] encodeAsBytes(AuthToken token) throws KrbException {
@@ -48,7 +56,35 @@ public class JwtTokenEncoder implements TokenEncoder {
JwtAuthToken jwtAuthToken = (JwtAuthToken) token;
JWT jwt = jwtAuthToken.getJwt();
- String tokenStr = jwt.serialize();
+ String tokenStr = null;
+ // Encrypt
+ if (encryptionKey != null) {
+ JWEHeader header = new JWEHeader(jweAlgorithm, encryptionMethod);
+ EncryptedJWT encryptedJWT = null;
+ try {
+ encryptedJWT = new EncryptedJWT(header, jwt.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new KrbException("Failed to get JWT claims set", e);
+ }
+ try {
+ encryptedJWT.encrypt(new RSAEncrypter(encryptionKey));
+ } catch (JOSEException e) {
+ throw new KrbException("Failed to encrypt the encrypted JWT", e);
+ }
+ tokenStr = encryptedJWT.serialize();
+
+ } else {
+ tokenStr = jwt.serialize();
+ }
return tokenStr;
}
+
+ /**
+ * set the encryption key
+ *
+ * @param key a public key
+ */
+ public static void setEncryptionKey(RSAPublicKey key) {
+ encryptionKey = key;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/d0f33b01/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java b/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
index 82fa888..da5422b 100644
--- a/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
+++ b/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
@@ -27,6 +27,11 @@ import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -84,4 +89,35 @@ public class TokenTest {
Assertions.assertThat(token2.getSubject()).isEqualTo(SUBJECT);
Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
}
+
+ @Test
+ public void testTokenWithEncryptedJWT() throws Exception {
+ setEncryptKey();
+ TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider().createTokenEncoder();
+ String tokenStr = tokenEncoder.encodeAsString(authToken);
+ System.out.println("Auth token: " + tokenStr);
+ Assertions.assertThat(tokenStr).isNotNull();
+
+ TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
+ AuthToken token2 = tokenDecoder.decodeFromString(tokenStr);
+ System.out.println("Decoded token's subject: " + token2.getSubject());
+ Assertions.assertThat(token2.getSubject()).isEqualTo(SUBJECT);
+ Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
+ }
+
+ private void setEncryptKey() {
+ KeyPair encryptionKeyPair = getKeyPair();
+ JwtTokenEncoder.setEncryptionKey((RSAPublicKey) encryptionKeyPair.getPublic());
+ JwtTokenDecoder.setDecryptionKey((RSAPrivateKey) encryptionKeyPair.getPrivate());
+ }
+
+ private KeyPair getKeyPair() {
+ KeyPairGenerator kpg = null;
+ try {
+ kpg = KeyPairGenerator.getInstance("RSA");
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return kpg.generateKeyPair();
+ }
}
[2/2] directory-kerby git commit: DIRKRB-194 Token signature
verification. Contributed by Jiajia
Posted by dr...@apache.org.
DIRKRB-194 Token signature verification. Contributed by Jiajia
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/9f2fe83c
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/9f2fe83c
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/9f2fe83c
Branch: refs/heads/master
Commit: 9f2fe83c1f8e6c294c095dfb6e10af43ec450cea
Parents: d0f33b0
Author: Drankye <dr...@gmail.com>
Authored: Mon Mar 30 20:45:42 2015 +0800
Committer: Drankye <dr...@gmail.com>
Committed: Mon Mar 30 20:45:42 2015 +0800
----------------------------------------------------------------------
.../provider/token/JwtTokenDecoder.java | 64 ++++++++++++++++++--
.../provider/token/JwtTokenEncoder.java | 51 +++++++++++++++-
.../kerberos/provider/token/TokenTest.java | 37 +++++++++++
3 files changed, 146 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f2fe83c/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
index c915ae1..d662dff 100644
--- a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
+++ b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenDecoder.java
@@ -20,16 +20,20 @@
package org.apache.kerby.kerberos.provider.token;
import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSADecrypter;
+import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.EncryptedJWT;
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTParser;
import com.nimbusds.jwt.PlainJWT;
+import com.nimbusds.jwt.SignedJWT;
import org.apache.kerby.kerberos.kerb.provider.TokenDecoder;
import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
import java.io.IOException;
import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
/**
@@ -37,6 +41,7 @@ import java.text.ParseException;
*/
public class JwtTokenDecoder implements TokenDecoder {
private static RSAPrivateKey decryptionKey;
+ private static RSAPublicKey verifyKey;
@Override
public AuthToken decodeFromBytes(byte[] content) throws IOException {
@@ -65,10 +70,36 @@ public class JwtTokenDecoder implements TokenDecoder {
} else if (jwt instanceof EncryptedJWT) {
EncryptedJWT encryptedJWT = (EncryptedJWT) jwt;
decryptEncryptedJWT(encryptedJWT);
- try {
- return new JwtAuthToken(encryptedJWT.getJWTClaimsSet());
- } catch (ParseException e) {
- throw new IOException("Failed to get JWT claims set", e);
+ SignedJWT signedJWT = encryptedJWT.getPayload().toSignedJWT();
+ if (signedJWT != null) {
+ boolean success = verifySignedJWT(signedJWT);
+ if (success) {
+ try {
+ return new JwtAuthToken(signedJWT.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ } else {
+ return null;
+ }
+ } else {
+ try {
+ return new JwtAuthToken(encryptedJWT.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ }
+ } else if (jwt instanceof SignedJWT) {
+ SignedJWT signedJWT = (SignedJWT) jwt;
+ boolean success = verifySignedJWT(signedJWT);
+ if (success) {
+ try {
+ return new JwtAuthToken(signedJWT.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new IOException("Failed to get JWT claims set", e);
+ }
+ } else {
+ return null;
}
} else {
throw new IOException("Unexpected JWT type: " + jwt);
@@ -97,4 +128,29 @@ public class JwtTokenDecoder implements TokenDecoder {
public static void setDecryptionKey(RSAPrivateKey key) {
decryptionKey = key;
}
+
+ /**
+ * verify the Signed JWT
+ *
+ * @param signedJWT
+ * @return whether verify success
+ */
+ public boolean verifySignedJWT(SignedJWT signedJWT) throws IOException {
+ JWSVerifier verifier = new RSASSAVerifier(verifyKey);
+ try {
+ return signedJWT.verify(verifier);
+ } catch (JOSEException e) {
+ throw new IOException("Failed to verify the signed JWT", e);
+ }
+ }
+
+ /**
+ * set the verify key
+ *
+ * @param key a public key
+ */
+ public static void setVerifyKey(RSAPublicKey key) {
+ verifyKey = key;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f2fe83c/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
index 07b5c3e..69668f6 100644
--- a/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
+++ b/kerby-provider/token-provider/src/main/java/org/apache/kerby/kerberos/provider/token/JwtTokenEncoder.java
@@ -23,13 +23,21 @@ import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.JWEHeader;
+import com.nimbusds.jose.JWEObject;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.JWSSigner;
+import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.RSAEncrypter;
+import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jwt.EncryptedJWT;
import com.nimbusds.jwt.JWT;
+import com.nimbusds.jwt.SignedJWT;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.provider.TokenEncoder;
import org.apache.kerby.kerberos.kerb.spec.base.AuthToken;
+import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
@@ -40,6 +48,8 @@ public class JwtTokenEncoder implements TokenEncoder {
private static JWEAlgorithm jweAlgorithm = JWEAlgorithm.RSA_OAEP;
private static EncryptionMethod encryptionMethod = EncryptionMethod.A128GCM;
private static RSAPublicKey encryptionKey;
+ private static JWSAlgorithm jwsAlgorithm = JWSAlgorithm.RS256;
+ private static RSAPrivateKey signKey;
@Override
public byte[] encodeAsBytes(AuthToken token) throws KrbException {
@@ -57,8 +67,36 @@ public class JwtTokenEncoder implements TokenEncoder {
JWT jwt = jwtAuthToken.getJwt();
String tokenStr = null;
- // Encrypt
- if (encryptionKey != null) {
+ if (signKey != null) {
+ // Create signer with the private key
+ JWSSigner signer = new RSASSASigner(signKey);
+ SignedJWT signedJWT = null;
+ try {
+ signedJWT = new SignedJWT(new JWSHeader(jwsAlgorithm), jwt.getJWTClaimsSet());
+ } catch (ParseException e) {
+ throw new KrbException("Failed to get JWT claims set", e);
+ }
+ try {
+ signedJWT.sign(signer);
+ } catch (JOSEException e) {
+ throw new KrbException("Failed to sign the Signed JWT", e);
+ }
+ // Encrypt
+ if (encryptionKey != null) {
+ // Create JWE object with signedJWT as payload
+ JWEObject jweObject = new JWEObject(
+ new JWEHeader.Builder(jweAlgorithm, encryptionMethod).contentType("JWT").build(),
+ new Payload(signedJWT));
+ try {
+ jweObject.encrypt(new RSAEncrypter(encryptionKey));
+ } catch (JOSEException e) {
+ throw new KrbException("Failed to encrypt the JWE object", e);
+ }
+ tokenStr = jweObject.serialize();
+ } else {
+ tokenStr = signedJWT.serialize();
+ }
+ } else if (encryptionKey != null) {
JWEHeader header = new JWEHeader(jweAlgorithm, encryptionMethod);
EncryptedJWT encryptedJWT = null;
try {
@@ -87,4 +125,13 @@ public class JwtTokenEncoder implements TokenEncoder {
public static void setEncryptionKey(RSAPublicKey key) {
encryptionKey = key;
}
+
+ /**
+ * set the sign key
+ *
+ * @param key a private key
+ */
+ public static void setSignKey(RSAPrivateKey key) {
+ signKey = key;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f2fe83c/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
----------------------------------------------------------------------
diff --git a/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java b/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
index da5422b..2baa3be 100644
--- a/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
+++ b/kerby-provider/token-provider/src/test/java/org/apache/kerby/kerberos/provider/token/TokenTest.java
@@ -105,6 +105,37 @@ public class TokenTest {
Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
}
+ @Test
+ public void testTokenWithSignedJWT() throws Exception {
+ setSignKey();
+ TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider().createTokenEncoder();
+ String tokenStr = tokenEncoder.encodeAsString(authToken);
+ System.out.println("Auth token: " + tokenStr);
+ Assertions.assertThat(tokenStr).isNotNull();
+
+ TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
+ AuthToken token2 = tokenDecoder.decodeFromString(tokenStr);
+ System.out.println("Decoded token's subject: " + token2.getSubject());
+ Assertions.assertThat(token2.getSubject()).isEqualTo(SUBJECT);
+ Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
+ }
+
+ @Test
+ public void testTokenWithSingedAndEncryptedJWT() throws Exception {
+ setSignKey();
+ setEncryptKey();
+ TokenEncoder tokenEncoder = KrbRuntime.getTokenProvider().createTokenEncoder();
+ String tokenStr = tokenEncoder.encodeAsString(authToken);
+ System.out.println("Auth token: " + tokenStr);
+ Assertions.assertThat(tokenStr).isNotNull();
+
+ TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
+ AuthToken token2 = tokenDecoder.decodeFromString(tokenStr);
+ System.out.println("Decoded token's subject: " + token2.getSubject());
+ Assertions.assertThat(token2.getSubject()).isEqualTo(SUBJECT);
+ Assertions.assertThat(token2.getIssuer()).isEqualTo(ISSUER);
+ }
+
private void setEncryptKey() {
KeyPair encryptionKeyPair = getKeyPair();
JwtTokenEncoder.setEncryptionKey((RSAPublicKey) encryptionKeyPair.getPublic());
@@ -120,4 +151,10 @@ public class TokenTest {
}
return kpg.generateKeyPair();
}
+
+ private void setSignKey() {
+ KeyPair signKeyPair = getKeyPair();
+ JwtTokenEncoder.setSignKey((RSAPrivateKey) signKeyPair.getPrivate());
+ JwtTokenDecoder.setVerifyKey((RSAPublicKey)signKeyPair.getPublic());
+ }
}