Skip to content

Commit

Permalink
Merge pull request #4 from longgt/feature/key-id-uuid
Browse files Browse the repository at this point in the history
Add UUID as key id generator
  • Loading branch information
longgt authored Jun 7, 2024
2 parents b86341b + 14eace4 commit 6cab8fe
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ usage: java -jar json-web-key-generator.jar -t <keyType> [options]
-i,--id <arg> Key ID (optional), one will be generated if not
defined
-g,--idGenerator <arg> Key ID generation method (optional). Can be one
of: date, timestamp, sha256, sha384, sha512, none. If
of: date, timestamp, sha256, sha384, sha512, uuid, none. If
omitted, generator method defaults to
'timestamp'.
-I,--noGenerateId <deprecated> Don't generate a Key ID.
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/mitre/jose/jwk/ECKeyMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public static ECKey make(Curve crv, KeyUse keyUse, Algorithm keyAlg, KeyIdGenera
requiredParams.put(JWKParameterNames.KEY_TYPE, KeyType.EC.getValue());
requiredParams.put(JWKParameterNames.ELLIPTIC_CURVE_X_COORDINATE, x.toString());
requiredParams.put(JWKParameterNames.ELLIPTIC_CURVE_Y_COORDINATE, y.toString());
requiredParams.put(JWKParameterNames.PUBLIC_KEY_USE, keyUse);

ECKey ecKey = new ECKey.Builder(crv, pub)
.privateKey(priv)
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/org/mitre/jose/jwk/KeyIdGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -34,23 +35,27 @@ public class KeyIdGenerator {
});

public static KeyIdGenerator SHA256 = new KeyIdGenerator("sha256", (params) -> {
final String json = JSONObjectUtils.toJSONString(params);
final String json = JSONObjectUtils.toJSONString(normalizeParams(params));
byte[] bytes = Hashing.sha256().hashBytes(json.getBytes(StandardCharset.UTF_8)).asBytes();
return Base64URL.encode(bytes).toString();
});

public static KeyIdGenerator SHA384 = new KeyIdGenerator("sha384", (params) -> {
final String json = JSONObjectUtils.toJSONString(params);
final String json = JSONObjectUtils.toJSONString(normalizeParams(params));
byte[] bytes = Hashing.sha384().hashBytes(json.getBytes(StandardCharset.UTF_8)).asBytes();
return Base64URL.encode(bytes).toString();
});

public static KeyIdGenerator SHA512 = new KeyIdGenerator("sha512", (params) -> {
final String json = JSONObjectUtils.toJSONString(params);
final String json = JSONObjectUtils.toJSONString(normalizeParams(params));
byte[] bytes = Hashing.sha512().hashBytes(json.getBytes(StandardCharset.UTF_8)).asBytes();
return Base64URL.encode(bytes).toString();
});

public static KeyIdGenerator UUID = new KeyIdGenerator("uuid", (params) -> {
return java.util.UUID.randomUUID().toString();
});

public static KeyIdGenerator NONE = new KeyIdGenerator("none", (params) -> {
return null;
});
Expand All @@ -72,7 +77,7 @@ public String getName() {
}

public static List<KeyIdGenerator> values() {
return List.of(DATE, TIMESTAMP, SHA256, SHA384, SHA512, NONE);
return List.of(DATE, TIMESTAMP, SHA256, SHA384, SHA512, UUID, NONE);
}

public static KeyIdGenerator get(String name) {
Expand All @@ -85,5 +90,12 @@ public static KeyIdGenerator get(String name) {
public static KeyIdGenerator specified(String kid) {
return new KeyIdGenerator(null, (params) -> kid);
}

private static Map<String, Object> normalizeParams(final Map<String, Object> params) {
Map<String, Object> requiredParams = new LinkedHashMap<>(params);
requiredParams.remove(JWKParameterNames.PUBLIC_KEY_USE);

return requiredParams;
}
}

1 change: 1 addition & 0 deletions src/main/java/org/mitre/jose/jwk/OKPKeyMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public static OctetKeyPair make(Curve keyCurve, KeyUse keyUse, Algorithm keyAlg,
requiredParams.put(JWKParameterNames.OKP_SUBTYPE, keyCurve.toString());
requiredParams.put(JWKParameterNames.KEY_TYPE, KeyType.OKP.getValue());
requiredParams.put(JWKParameterNames.OKP_PUBLIC_KEY, Base64URL.encode(x).toString());
requiredParams.put(JWKParameterNames.PUBLIC_KEY_USE, keyUse);

// Now that we have the raw numbers, export them as a JWK
OctetKeyPair jwk = new OctetKeyPair.Builder(keyCurve, Base64URL.encode(x))
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/mitre/jose/jwk/OctetSequenceKeyMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class OctetSequenceKeyMaker {
* @param keySize in bits
* @return
*/
public static OctetSequenceKey make(Integer keySize, KeyUse use, Algorithm alg, KeyIdGenerator kid) {
public static OctetSequenceKey make(Integer keySize, KeyUse keyUse, Algorithm alg, KeyIdGenerator kid) {

// holder for the random bytes
byte[] bytes = new byte[keySize / 8];
Expand All @@ -36,12 +36,13 @@ public static OctetSequenceKey make(Integer keySize, KeyUse use, Algorithm alg,
LinkedHashMap<String, Object> requiredParams = new LinkedHashMap<>();
requiredParams.put(JWKParameterNames.OCT_KEY_VALUE, encoded.toString());
requiredParams.put(JWKParameterNames.KEY_TYPE, KeyType.OCT.getValue());
requiredParams.put(JWKParameterNames.PUBLIC_KEY_USE, keyUse);

// make a key
OctetSequenceKey octetSequenceKey = new OctetSequenceKey.Builder(encoded)
.keyID(kid.generate(requiredParams))
.algorithm(alg)
.keyUse(use)
.keyUse(keyUse)
.build();

return octetSequenceKey;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/mitre/jose/jwk/RSAKeyMaker.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public static RSAKey make(Integer keySize, KeyUse keyUse, Algorithm keyAlg, KeyI
requiredParams.put(JWKParameterNames.RSA_EXPONENT, e.toString());
requiredParams.put(JWKParameterNames.KEY_TYPE, KeyType.RSA.getValue());
requiredParams.put(JWKParameterNames.RSA_MODULUS, n.toString());
requiredParams.put(JWKParameterNames.PUBLIC_KEY_USE, keyUse);

RSAKey rsaKey = new RSAKey.Builder(pub)
.privateKey(priv)
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/org/mitre/jose/jwk/ECKeyMakerTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.mitre.jose.jwk;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.UUID;

import org.junit.jupiter.api.Test;

import com.nimbusds.jose.JOSEException;
Expand Down Expand Up @@ -42,4 +45,13 @@ void sha512() throws JOSEException {
"kid should be same as " + hashAlg + " hashed value from method keyIDFromThumbprint");
}

@Test
void uuid() throws JOSEException {
KeyIdGenerator kidGenerator = KeyIdGenerator.UUID;
ECKey key = ECKeyMaker.make(Curve.P_256, KeyUse.SIGNATURE, JWSAlgorithm.ES256, kidGenerator);
assertDoesNotThrow(() -> {
UUID.fromString(key.getKeyID());
});
}

}
12 changes: 12 additions & 0 deletions src/test/java/org/mitre/jose/jwk/OKPKeyMakerTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.mitre.jose.jwk;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.UUID;

import org.junit.jupiter.api.Test;

import com.nimbusds.jose.JOSEException;
Expand Down Expand Up @@ -42,4 +45,13 @@ void sha512() throws JOSEException {
"kid should be same as " + hashAlg + " hashed value from method keyIDFromThumbprint");
}

@Test
void uuid() throws JOSEException {
KeyIdGenerator kidGenerator = KeyIdGenerator.UUID;
OctetKeyPair key = OKPKeyMaker.make(Curve.Ed25519, KeyUse.SIGNATURE, JWSAlgorithm.EdDSA, kidGenerator);
assertDoesNotThrow(() -> {
UUID.fromString(key.getKeyID());
});
}

}
12 changes: 12 additions & 0 deletions src/test/java/org/mitre/jose/jwk/OctetSequenceKeyMakerTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.mitre.jose.jwk;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.UUID;

import org.junit.jupiter.api.Test;

import com.nimbusds.jose.JOSEException;
Expand Down Expand Up @@ -41,4 +44,13 @@ void sha512() throws JOSEException {
"kid should be same as " + hashAlg + " hashed value from method keyIDFromThumbprint");
}

@Test
void uuid() throws JOSEException {
KeyIdGenerator kidGenerator = KeyIdGenerator.UUID;
OctetSequenceKey key = OctetSequenceKeyMaker.make(2048, KeyUse.SIGNATURE, JWSAlgorithm.HS256, kidGenerator);
assertDoesNotThrow(() -> {
UUID.fromString(key.getKeyID());
});
}

}
12 changes: 12 additions & 0 deletions src/test/java/org/mitre/jose/jwk/RSAKeyMakerTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.mitre.jose.jwk;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.UUID;

import org.junit.jupiter.api.Test;

import com.nimbusds.jose.JOSEException;
Expand Down Expand Up @@ -41,4 +44,13 @@ void sha512() throws JOSEException {
"kid should be same as " + hashAlg + " hashed value from method keyIDFromThumbprint");
}

@Test
void uuid() throws JOSEException {
KeyIdGenerator kidGenerator = KeyIdGenerator.UUID;
RSAKey key = RSAKeyMaker.make(2048, KeyUse.SIGNATURE, JWSAlgorithm.RS256, kidGenerator);
assertDoesNotThrow(() -> {
UUID.fromString(key.getKeyID());
});
}

}

0 comments on commit 6cab8fe

Please sign in to comment.