fix incorrect JWS implementation

This commit is contained in:
Bill Burke 2014-11-11 21:28:35 -05:00
parent d72bcebdf0
commit 0636cd898f
4 changed files with 99 additions and 27 deletions

View file

@ -58,81 +58,148 @@ public class JWSBuilder {
} }
} }
protected String encode(Algorithm alg, byte[] data, byte[] signature) { protected String encodeAll(StringBuffer encoding, byte[] signature) {
StringBuffer encoding = new StringBuffer();
encoding.append(encodeHeader(alg));
encoding.append('.'); encoding.append('.');
encoding.append(Base64Url.encode(data)); if (signature != null) {
encoding.append('.');
if (alg != Algorithm.none) {
encoding.append(Base64Url.encode(signature)); encoding.append(Base64Url.encode(signature));
} }
return encoding.toString(); return encoding.toString();
} }
protected void encode(Algorithm alg, byte[] data, StringBuffer encoding) {
encoding.append(encodeHeader(alg));
encoding.append('.');
encoding.append(Base64Url.encode(data));
}
protected byte[] marshalContent() { protected byte[] marshalContent() {
return contentBytes; return contentBytes;
} }
public class EncodingBuilder { public class EncodingBuilder {
public String none() { public String none() {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
return encode(Algorithm.none, data, null); encode(Algorithm.none, data, buffer);
return encodeAll(buffer, null);
} }
public String rsa256(PrivateKey privateKey) { public String rsa256(PrivateKey privateKey) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = RSAProvider.sign(data, Algorithm.RS256, privateKey); encode(Algorithm.RS256, data, buffer);
return encode(Algorithm.RS256, data, signature); byte[] signature = null;
try {
signature = RSAProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.RS256, privateKey);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String rsa384(PrivateKey privateKey) { public String rsa384(PrivateKey privateKey) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = RSAProvider.sign(data, Algorithm.RS384, privateKey); encode(Algorithm.RS384, data, buffer);
return encode(Algorithm.RS384, data, signature); byte[] signature = null;
try {
signature = RSAProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.RS384, privateKey);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String rsa512(PrivateKey privateKey) { public String rsa512(PrivateKey privateKey) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = RSAProvider.sign(data, Algorithm.RS512, privateKey); encode(Algorithm.RS512, data, buffer);
return encode(Algorithm.RS512, data, signature); byte[] signature = null;
try {
signature = RSAProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.RS512, privateKey);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String hmac256(byte[] sharedSecret) { public String hmac256(byte[] sharedSecret) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = HMACProvider.sign(data, Algorithm.HS256, sharedSecret); encode(Algorithm.HS256, data, buffer);
return encode(Algorithm.HS256, data, signature); byte[] signature = null;
try {
signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS256, sharedSecret);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String hmac384(byte[] sharedSecret) { public String hmac384(byte[] sharedSecret) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = HMACProvider.sign(data, Algorithm.HS384, sharedSecret); encode(Algorithm.HS384, data, buffer);
return encode(Algorithm.HS384, data, signature); byte[] signature = null;
try {
signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS384, sharedSecret);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String hmac512(byte[] sharedSecret) { public String hmac512(byte[] sharedSecret) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = HMACProvider.sign(data, Algorithm.HS512, sharedSecret); encode(Algorithm.HS512, data, buffer);
return encode(Algorithm.HS512, data, signature); byte[] signature = null;
try {
signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS512, sharedSecret);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String hmac256(SecretKey sharedSecret) { public String hmac256(SecretKey sharedSecret) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = HMACProvider.sign(data, Algorithm.HS256, sharedSecret); encode(Algorithm.HS256, data, buffer);
return encode(Algorithm.HS256, data, signature); byte[] signature = null;
try {
signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS256, sharedSecret);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String hmac384(SecretKey sharedSecret) { public String hmac384(SecretKey sharedSecret) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = HMACProvider.sign(data, Algorithm.HS384, sharedSecret); encode(Algorithm.HS384, data, buffer);
return encode(Algorithm.HS384, data, signature); byte[] signature = null;
try {
signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS384, sharedSecret);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
public String hmac512(SecretKey sharedSecret) { public String hmac512(SecretKey sharedSecret) {
StringBuffer buffer = new StringBuffer();
byte[] data = marshalContent(); byte[] data = marshalContent();
byte[] signature = HMACProvider.sign(data, Algorithm.HS512, sharedSecret); encode(Algorithm.HS512, data, buffer);
return encode(Algorithm.HS512, data, signature); byte[] signature = null;
try {
signature = HMACProvider.sign(buffer.toString().getBytes("UTF-8"), Algorithm.HS512, sharedSecret);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return encodeAll(buffer, signature);
} }
} }
} }

View file

@ -15,6 +15,7 @@ public class JWSInput {
String encodedHeader; String encodedHeader;
String encodedContent; String encodedContent;
String encodedSignature; String encodedSignature;
String encodedSignatureInput;
JWSHeader header; JWSHeader header;
byte[] content; byte[] content;
byte[] signature; byte[] signature;
@ -26,6 +27,7 @@ public class JWSInput {
if (parts.length < 2 || parts.length > 3) throw new IllegalArgumentException("Parsing error"); if (parts.length < 2 || parts.length > 3) throw new IllegalArgumentException("Parsing error");
encodedHeader = parts[0]; encodedHeader = parts[0];
encodedContent = parts[1]; encodedContent = parts[1];
encodedSignatureInput = encodedHeader + '.' + encodedContent;
try { try {
content = Base64Url.decode(encodedContent); content = Base64Url.decode(encodedContent);
if (parts.length > 2) { if (parts.length > 2) {
@ -55,6 +57,9 @@ public class JWSInput {
public String getEncodedSignature() { public String getEncodedSignature() {
return encodedSignature; return encodedSignature;
} }
public String getEncodedSignatureInput() {
return encodedSignatureInput;
}
public JWSHeader getHeader() { public JWSHeader getHeader() {
return header; return header;

View file

@ -74,7 +74,7 @@ public class HMACProvider {
public static boolean verify(JWSInput input, byte[] sharedSecret) { public static boolean verify(JWSInput input, byte[] sharedSecret) {
try { try {
byte[] signature = sign(input.getContent(), input.getHeader().getAlgorithm(), sharedSecret); byte[] signature = sign(input.getEncodedSignatureInput().getBytes("UTF-8"), input.getHeader().getAlgorithm(), sharedSecret);
String x = Base64Url.encode(signature); String x = Base64Url.encode(signature);
return x.equals(input.getEncodedSignature()); return x.equals(input.getEncodedSignature());
} catch (Exception e) { } catch (Exception e) {

View file

@ -49,7 +49,7 @@ public class RSAProvider {
try { try {
Signature verifier = getSignature(input.getHeader().getAlgorithm()); Signature verifier = getSignature(input.getHeader().getAlgorithm());
verifier.initVerify(publicKey); verifier.initVerify(publicKey);
verifier.update(input.getContent()); verifier.update(input.getEncodedSignatureInput().getBytes("UTF-8"));
return verifier.verify(input.getSignature()); return verifier.verify(input.getSignature());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);