encryption completed, decryption WIP
parent
cee44de3d1
commit
99a574d303
|
@ -20,6 +20,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
|
||||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||||
<artifactId>spring-security-oauth2</artifactId>
|
<artifactId>spring-security-oauth2</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<artifactId></artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<properties>
|
<properties>
|
||||||
<java-version>1.6</java-version>
|
<java-version>1.6</java-version>
|
||||||
|
|
|
@ -66,6 +66,11 @@ public class Jwe extends Jwt {
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the canonical encoded string of this JWE, the header in Base64, a period ".", the encrypted key in Base64, a period ".",
|
||||||
|
* the ciphertext in Base64, a period ".", and the signature, or integrity value, in Base64.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getSignatureBase() + "." + Strings.nullToEmpty(this.signature);
|
return getSignatureBase() + "." + Strings.nullToEmpty(this.signature);
|
||||||
|
@ -105,6 +110,7 @@ public class Jwe extends Jwt {
|
||||||
String i64 = parts.get(3);
|
String i64 = parts.get(3);
|
||||||
|
|
||||||
Jwe jwe = new Jwe(new JweHeader(h64), e64.getBytes(), c64.getBytes(), i64);
|
Jwe jwe = new Jwe(new JweHeader(h64), e64.getBytes(), c64.getBytes(), i64);
|
||||||
|
//Jwe jwe = new Jwe(new JweHeader(h64), e64.getBytes(), new ClaimSet(c64), i64);
|
||||||
|
|
||||||
return jwe;
|
return jwe;
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,111 @@
|
||||||
package org.mitre.jwt.encryption;
|
package org.mitre.jwt.encryption;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
import org.mitre.jwe.model.Jwe;
|
||||||
import org.mitre.jwt.encryption.impl.RsaDecrypter;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class AbstractJweDecrypter implements JwtDecrypter {
|
public abstract class AbstractJweDecrypter implements JwtDecrypter {
|
||||||
|
|
||||||
@Override
|
private Jwe jwe;
|
||||||
public Jwe decrypt(Jwe jwe) {
|
|
||||||
String alg = jwe.getHeader().getAlgorithm();
|
|
||||||
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
|
||||||
|
|
||||||
RsaDecrypter decrypter = new RsaDecrypter(jwe);
|
private PrivateKey privateKey;
|
||||||
jwe.setCiphertext(decrypter.decryptCipherText(jwe).getBytes()); //TODO: When decrypting, should it return a jwe or jwt?
|
|
||||||
jwe.setEncryptedKey(decrypter.decryptEncryptionKey(jwe));
|
|
||||||
|
|
||||||
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
private PublicKey publicKey;
|
||||||
|
|
||||||
throw new IllegalArgumentException("Cannot use Hmac for decryption");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Not a valid decrypting algorithm");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public Jwe getJwe() {
|
||||||
return jwe;
|
return jwe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setJwe(Jwe jwe) {
|
||||||
|
this.jwe = jwe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrivateKey getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(PrivateKey privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublicKey getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicKey(PublicKey publicKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String decryptCipherText(Jwe jwe) {
|
||||||
|
Cipher cipher;
|
||||||
|
String clearTextString = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
|
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
|
||||||
|
clearTextString = new String(clearText);
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return clearTextString;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] decryptEncryptionKey(Jwe jwe) {
|
||||||
|
Cipher cipher;
|
||||||
|
byte[] unencryptedKey = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateKey);//TODO: Keys are null, get them from keystore. Placeholder
|
||||||
|
unencryptedKey = cipher.doFinal(jwe.getEncryptedKey());
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalBlockSizeException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (BadPaddingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return unencryptedKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,31 +11,19 @@ import javax.crypto.IllegalBlockSizeException;
|
||||||
import javax.crypto.NoSuchPaddingException;
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
import org.mitre.jwe.model.Jwe;
|
||||||
import org.mitre.jwe.model.JweHeader;
|
|
||||||
import org.mitre.jwt.model.JwtClaims;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
|
|
||||||
private Jwe jwe;
|
|
||||||
|
|
||||||
private JweHeader header;
|
|
||||||
|
|
||||||
private JwtClaims claims;
|
|
||||||
|
|
||||||
private String signature;
|
|
||||||
|
|
||||||
private byte[] encryptedKey;
|
private byte[] encryptedKey;
|
||||||
|
|
||||||
private byte[] cipherText;
|
private byte[] cipherText;
|
||||||
|
|
||||||
public Jwe getJwe() {
|
private RSAPublicKey publicKey;
|
||||||
return jwe;
|
|
||||||
}
|
private RSAPrivateKey privateKey;
|
||||||
|
|
||||||
|
|
||||||
public void setJwe(Jwe jwe) {
|
|
||||||
this.jwe = jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getEncryptecKey() {
|
public byte[] getEncryptecKey() {
|
||||||
return encryptedKey;
|
return encryptedKey;
|
||||||
|
@ -45,30 +33,6 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
this.encryptedKey = encryptedKey;
|
this.encryptedKey = encryptedKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JweHeader getHeader() {
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeader(JweHeader header) {
|
|
||||||
this.header = header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JwtClaims getClaims() {
|
|
||||||
return claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClaims(JwtClaims claims) {
|
|
||||||
this.claims = claims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSignature(String signature) {
|
|
||||||
this.signature = signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getCipherText() {
|
public byte[] getCipherText() {
|
||||||
return cipherText;
|
return cipherText;
|
||||||
}
|
}
|
||||||
|
@ -80,9 +44,8 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
|
|
||||||
public byte[] encryptKey(Jwe jwe){
|
public byte[] encryptKey(Jwe jwe){
|
||||||
|
|
||||||
RSAPublicKey publicKey = null; // TODO: placeholder
|
|
||||||
RSAPrivateKey privateKey = null;
|
|
||||||
|
|
||||||
|
//TODO:Get keys from keystore, currently null
|
||||||
Cipher cipher;
|
Cipher cipher;
|
||||||
try {
|
try {
|
||||||
cipher = Cipher.getInstance("RSA");
|
cipher = Cipher.getInstance("RSA");
|
||||||
|
@ -112,13 +75,13 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
|
|
||||||
public byte[] encryptClaims(Jwe jwe) {
|
public byte[] encryptClaims(Jwe jwe) {
|
||||||
|
|
||||||
RSAPublicKey publicKey = null; // TODO: placeholder
|
|
||||||
|
|
||||||
|
//TODO:Get keys from keystore, currently null
|
||||||
Cipher cipher;
|
Cipher cipher;
|
||||||
try {
|
try {
|
||||||
cipher = Cipher.getInstance("RSA");
|
cipher = Cipher.getInstance("RSA");
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
cipherText = cipher.doFinal(claims.toString().getBytes());
|
cipherText = cipher.doFinal(jwe.getClaims().toString().getBytes());
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
|
@ -141,5 +104,7 @@ public abstract class AbstractJweEncrypter implements JwtEncrypter {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract Jwe encryptAndSign(Jwe jwe);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.mitre.jwe.model.Jwe;
|
||||||
|
|
||||||
public interface JwtDecrypter {
|
public interface JwtDecrypter {
|
||||||
|
|
||||||
public Jwe decrypt(Jwe jwe);
|
public Jwe decrypt(String encryptedJwe);
|
||||||
|
|
||||||
public String decryptCipherText(Jwe jwe);
|
public String decryptCipherText(Jwe jwe);
|
||||||
|
|
||||||
|
|
|
@ -1,115 +1,41 @@
|
||||||
package org.mitre.jwt.encryption.impl;
|
package org.mitre.jwt.encryption.impl;
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
import org.mitre.jwe.model.Jwe;
|
||||||
import org.mitre.jwt.encryption.AbstractJweDecrypter;
|
import org.mitre.jwt.encryption.AbstractJweDecrypter;
|
||||||
|
import org.mitre.jwt.model.JwtHeader;
|
||||||
|
|
||||||
public class RsaDecrypter extends AbstractJweDecrypter {
|
public class RsaDecrypter extends AbstractJweDecrypter {
|
||||||
|
|
||||||
private Jwe jwe;
|
|
||||||
|
|
||||||
private PrivateKey privateKey;
|
|
||||||
|
|
||||||
private PublicKey publicKey;
|
|
||||||
|
|
||||||
public RsaDecrypter(Jwe jwe) {
|
public RsaDecrypter(Jwe jwe) {
|
||||||
setJwe(jwe);
|
setJwe(jwe);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jwe getJwe() {
|
@Override
|
||||||
|
public Jwe decrypt(String encryptedJwe) {
|
||||||
|
|
||||||
|
Jwe jwe = Jwe.parse(encryptedJwe);
|
||||||
|
|
||||||
|
String alg = jwe.getHeader().getAlgorithm();
|
||||||
|
if(alg.equals("RS256") || alg.equals("RS384") || alg.equals("RS512")) {
|
||||||
|
|
||||||
|
String decodedHeader = new String(Base64.decodeBase64(jwe.getHeader().toString()));
|
||||||
|
JwtHeader unencryptedHeader = new JwtHeader(decodedHeader);
|
||||||
|
String decodedSig = new String(Base64.decodeBase64(jwe.getSignature()));
|
||||||
|
|
||||||
|
jwe.setHeader(unencryptedHeader);
|
||||||
|
jwe.setCiphertext(decryptCipherText(jwe).getBytes());
|
||||||
|
jwe.setEncryptedKey(decryptEncryptionKey(jwe));
|
||||||
|
jwe.setSignature(decodedSig);
|
||||||
|
|
||||||
|
} else if(alg.equals("HS256") || alg.equals("HS384") || alg.equals("HS512")){
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Cannot use Hmac for decryption");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Not a valid decrypting algorithm");
|
||||||
|
}
|
||||||
return jwe;
|
return jwe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJwe(Jwe jwe) {
|
|
||||||
this.jwe = jwe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrivateKey getPrivateKey() {
|
|
||||||
return privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrivateKey(PrivateKey privateKey) {
|
|
||||||
this.privateKey = privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PublicKey getPublicKey() {
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPublicKey(PublicKey publicKey) {
|
|
||||||
this.publicKey = publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String decryptCipherText(Jwe jwe) {
|
|
||||||
Cipher cipher;
|
|
||||||
String clearTextString = null;
|
|
||||||
try {
|
|
||||||
|
|
||||||
cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
byte[] clearText = cipher.doFinal(jwe.getCiphertext());
|
|
||||||
clearTextString = new String(clearText);
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return clearTextString;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] decryptEncryptionKey(Jwe jwe) {
|
|
||||||
Cipher cipher;
|
|
||||||
byte[] unencryptedKey = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
cipher = Cipher.getInstance("RSA");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
unencryptedKey = cipher.doFinal(jwe.getEncryptedKey());
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return unencryptedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,21 @@ package org.mitre.jwt.encryption.impl;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
import org.mitre.jwe.model.Jwe;
|
import org.mitre.jwe.model.Jwe;
|
||||||
|
import org.mitre.jwe.model.JweHeader;
|
||||||
import org.mitre.jwt.encryption.AbstractJweEncrypter;
|
import org.mitre.jwt.encryption.AbstractJweEncrypter;
|
||||||
|
import org.mitre.jwt.model.JwtClaims;
|
||||||
import org.mitre.jwt.signer.impl.RsaSigner;
|
import org.mitre.jwt.signer.impl.RsaSigner;
|
||||||
|
|
||||||
public class RsaEncrypter extends AbstractJweEncrypter {
|
public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
|
|
||||||
|
private Jwe jwe;
|
||||||
|
|
||||||
|
private JweHeader header;
|
||||||
|
|
||||||
|
private JwtClaims claims;
|
||||||
|
|
||||||
|
private String signature;
|
||||||
|
|
||||||
public RsaEncrypter(Jwe jwe) {
|
public RsaEncrypter(Jwe jwe) {
|
||||||
setJwe(jwe);
|
setJwe(jwe);
|
||||||
setHeader(jwe.getHeader());
|
setHeader(jwe.getHeader());
|
||||||
|
@ -15,6 +25,39 @@ public class RsaEncrypter extends AbstractJweEncrypter {
|
||||||
setSignature(jwe.getSignature());
|
setSignature(jwe.getSignature());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Jwe getJwe() {
|
||||||
|
return jwe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJwe(Jwe jwe) {
|
||||||
|
this.jwe = jwe;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JweHeader getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(JweHeader header) {
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JwtClaims getClaims() {
|
||||||
|
return claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClaims(JwtClaims claims) {
|
||||||
|
this.claims = claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignature(String signature) {
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Jwe encryptAndSign(Jwe jwe) {
|
public Jwe encryptAndSign(Jwe jwe) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue