use of com.google.crypto.tink.proto.JwtRsaSsaPkcs1Algorithm in project tink by google.
the class JwkSetConverter method convertToRsaSsaPkcs1Key.
private static KeyData convertToRsaSsaPkcs1Key(JsonObject jsonKey) throws IOException {
JwtRsaSsaPkcs1Algorithm algorithm;
switch(getStringItem(jsonKey, "alg")) {
case "RS256":
algorithm = JwtRsaSsaPkcs1Algorithm.RS256;
break;
case "RS384":
algorithm = JwtRsaSsaPkcs1Algorithm.RS384;
break;
case "RS512":
algorithm = JwtRsaSsaPkcs1Algorithm.RS512;
break;
default:
throw new IOException("Unknown Rsa Algorithm: " + getStringItem(jsonKey, "alg"));
}
if (jsonKey.has("p") || jsonKey.has("q") || jsonKey.has("dp") || jsonKey.has("dq") || jsonKey.has("d") || jsonKey.has("qi")) {
throw new UnsupportedOperationException("importing RSA private keys is not implemented");
}
expectStringItem(jsonKey, "kty", "RSA");
validateUseIsSig(jsonKey);
validateKeyOpsIsVerify(jsonKey);
JwtRsaSsaPkcs1PublicKey.Builder pkcs1PubKeyBuilder = JwtRsaSsaPkcs1PublicKey.newBuilder().setVersion(0).setAlgorithm(algorithm).setE(ByteString.copyFrom(Base64.urlSafeDecode(getStringItem(jsonKey, "e")))).setN(ByteString.copyFrom(Base64.urlSafeDecode(getStringItem(jsonKey, "n"))));
if (jsonKey.has("kid")) {
pkcs1PubKeyBuilder.setCustomKid(JwtRsaSsaPkcs1PublicKey.CustomKid.newBuilder().setValue(getStringItem(jsonKey, "kid")).build());
}
return KeyData.newBuilder().setTypeUrl(JWT_RSA_SSA_PKCS1_PUBLIC_KEY_URL).setValue(pkcs1PubKeyBuilder.build().toByteString()).setKeyMaterialType(KeyMaterialType.ASYMMETRIC_PUBLIC).build();
}
use of com.google.crypto.tink.proto.JwtRsaSsaPkcs1Algorithm in project tink by google.
the class JwtRsaSsaPkcs1SignKeyManagerTest method createSignVerifyTink_withDifferentHeaders.
@Test
public void createSignVerifyTink_withDifferentHeaders() throws Exception {
if (TestUtil.isTsan()) {
// We do not use assume because Theories expects to find something which is not skipped.
return;
}
KeyTemplate template = KeyTemplates.get("JWT_RS256_2048_F4");
KeysetHandle handle = KeysetHandle.generateNew(template);
Keyset keyset = CleartextKeysetHandle.getKeyset(handle);
JwtRsaSsaPkcs1PrivateKey keyProto = JwtRsaSsaPkcs1PrivateKey.parseFrom(keyset.getKey(0).getKeyData().getValue(), ExtensionRegistryLite.getEmptyRegistry());
RSAPrivateCrtKey privateKey = createPrivateKey(keyProto);
JwtRsaSsaPkcs1Algorithm algorithm = keyProto.getPublicKey().getAlgorithm();
Enums.HashType hash = JwtRsaSsaPkcs1VerifyKeyManager.hashForPkcs1Algorithm(algorithm);
RsaSsaPkcs1SignJce rawSigner = new RsaSsaPkcs1SignJce(privateKey, hash);
JwtPublicKeyVerify verifier = handle.getPublicKeysetHandle().getPrimitive(JwtPublicKeyVerify.class);
JwtValidator validator = JwtValidator.newBuilder().allowMissingExpiration().build();
String kid = JwtFormat.getKid(keyset.getKey(0).getKeyId(), keyset.getKey(0).getOutputPrefixType()).get();
JsonObject payload = new JsonObject();
payload.addProperty("jti", "jwtId");
// normal, valid token
JsonObject normalHeader = new JsonObject();
normalHeader.addProperty("alg", "RS256");
normalHeader.addProperty("kid", kid);
String validToken = generateSignedCompact(rawSigner, normalHeader, payload);
verifier.verifyAndDecode(validToken, validator);
// token without kid are rejected, even if they are valid.
JsonObject headerWithoutKid = new JsonObject();
headerWithoutKid.addProperty("alg", "RS256");
String tokenWithoutKid = generateSignedCompact(rawSigner, headerWithoutKid, payload);
assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(tokenWithoutKid, validator));
// token without algorithm in header
JsonObject headerWithoutAlg = new JsonObject();
headerWithoutAlg.addProperty("kid", kid);
String tokenWithoutAlg = generateSignedCompact(rawSigner, headerWithoutAlg, payload);
assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(tokenWithoutAlg, validator));
// invalid token with an incorrect algorithm in the header
JsonObject headerWithBadAlg = new JsonObject();
headerWithBadAlg.addProperty("alg", "PS256");
headerWithBadAlg.addProperty("kid", kid);
String tokenWithBadAlg = generateSignedCompact(rawSigner, headerWithBadAlg, payload);
assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(tokenWithBadAlg, validator));
// token with an unknown "kid" in the header is invalid
JsonObject headerWithUnknownKid = new JsonObject();
headerWithUnknownKid.addProperty("alg", "RS256");
headerWithUnknownKid.addProperty("kid", "unknown");
String tokenWithUnknownKid = generateSignedCompact(rawSigner, headerWithUnknownKid, payload);
assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(tokenWithUnknownKid, validator));
}
use of com.google.crypto.tink.proto.JwtRsaSsaPkcs1Algorithm in project tink by google.
the class JwtRsaSsaPkcs1SignKeyManager method selfTestKey.
private static final void selfTestKey(RSAPrivateCrtKey privateKey, JwtRsaSsaPkcs1PrivateKey keyProto) throws GeneralSecurityException {
java.security.KeyFactory kf = EngineFactory.KEY_FACTORY.getInstance("RSA");
RSAPublicKey publicKey = (RSAPublicKey) kf.generatePublic(new RSAPublicKeySpec(new BigInteger(1, keyProto.getPublicKey().getN().toByteArray()), new BigInteger(1, keyProto.getPublicKey().getE().toByteArray())));
// Sign and verify a test message to make sure that the key is correct.
JwtRsaSsaPkcs1Algorithm algorithm = keyProto.getPublicKey().getAlgorithm();
Enums.HashType hash = JwtRsaSsaPkcs1VerifyKeyManager.hashForPkcs1Algorithm(algorithm);
SelfKeyTestValidators.validateRsaSsaPkcs1(privateKey, publicKey, hash);
}
use of com.google.crypto.tink.proto.JwtRsaSsaPkcs1Algorithm in project tink by google.
the class JwtRsaSsaPkcs1SignKeyManager method keyFactory.
@Override
public KeyFactory<JwtRsaSsaPkcs1KeyFormat, JwtRsaSsaPkcs1PrivateKey> keyFactory() {
return new KeyFactory<JwtRsaSsaPkcs1KeyFormat, JwtRsaSsaPkcs1PrivateKey>(JwtRsaSsaPkcs1KeyFormat.class) {
@Override
public void validateKeyFormat(JwtRsaSsaPkcs1KeyFormat keyFormat) throws GeneralSecurityException {
Validators.validateRsaModulusSize(keyFormat.getModulusSizeInBits());
Validators.validateRsaPublicExponent(new BigInteger(1, keyFormat.getPublicExponent().toByteArray()));
}
@Override
public JwtRsaSsaPkcs1KeyFormat parseKeyFormat(ByteString byteString) throws InvalidProtocolBufferException {
return JwtRsaSsaPkcs1KeyFormat.parseFrom(byteString, ExtensionRegistryLite.getEmptyRegistry());
}
@Override
public JwtRsaSsaPkcs1PrivateKey deriveKey(JwtRsaSsaPkcs1KeyFormat format, InputStream inputStream) {
throw new UnsupportedOperationException();
}
@Override
public JwtRsaSsaPkcs1PrivateKey createKey(JwtRsaSsaPkcs1KeyFormat format) throws GeneralSecurityException {
JwtRsaSsaPkcs1Algorithm algorithm = format.getAlgorithm();
KeyPairGenerator keyGen = EngineFactory.KEY_PAIR_GENERATOR.getInstance("RSA");
RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(format.getModulusSizeInBits(), new BigInteger(1, format.getPublicExponent().toByteArray()));
keyGen.initialize(spec);
KeyPair keyPair = keyGen.generateKeyPair();
RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) keyPair.getPrivate();
// Creates JwtRsaSsaPkcs1PublicKey.
JwtRsaSsaPkcs1PublicKey pkcs1PubKey = JwtRsaSsaPkcs1PublicKey.newBuilder().setVersion(getVersion()).setAlgorithm(algorithm).setE(ByteString.copyFrom(pubKey.getPublicExponent().toByteArray())).setN(ByteString.copyFrom(pubKey.getModulus().toByteArray())).build();
// Creates JwtRsaSsaPkcs1PrivateKey.
return JwtRsaSsaPkcs1PrivateKey.newBuilder().setVersion(getVersion()).setPublicKey(pkcs1PubKey).setD(ByteString.copyFrom(privKey.getPrivateExponent().toByteArray())).setP(ByteString.copyFrom(privKey.getPrimeP().toByteArray())).setQ(ByteString.copyFrom(privKey.getPrimeQ().toByteArray())).setDp(ByteString.copyFrom(privKey.getPrimeExponentP().toByteArray())).setDq(ByteString.copyFrom(privKey.getPrimeExponentQ().toByteArray())).setCrt(ByteString.copyFrom(privKey.getCrtCoefficient().toByteArray())).build();
}
/**
* List of default templates to generate tokens with algorithms "RS256", "RS384" or "RS512".
* Use the template with the "_RAW" suffix if you want to generate tokens without a "kid"
* header.
*/
@Override
public Map<String, KeyFactory.KeyFormat<JwtRsaSsaPkcs1KeyFormat>> keyFormats() {
Map<String, KeyFactory.KeyFormat<JwtRsaSsaPkcs1KeyFormat>> result = new HashMap<>();
result.put("JWT_RS256_2048_F4_RAW", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS256, 2048, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.RAW));
result.put("JWT_RS256_2048_F4", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS256, 2048, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.TINK));
result.put("JWT_RS256_3072_F4_RAW", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS256, 3072, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.RAW));
result.put("JWT_RS256_3072_F4", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS256, 3072, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.TINK));
result.put("JWT_RS384_3072_F4_RAW", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS384, 3072, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.RAW));
result.put("JWT_RS384_3072_F4", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS384, 3072, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.TINK));
result.put("JWT_RS512_4096_F4_RAW", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS512, 4096, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.RAW));
result.put("JWT_RS512_4096_F4", createKeyFormat(JwtRsaSsaPkcs1Algorithm.RS512, 4096, RSAKeyGenParameterSpec.F4, KeyTemplate.OutputPrefixType.TINK));
return Collections.unmodifiableMap(result);
}
};
}
use of com.google.crypto.tink.proto.JwtRsaSsaPkcs1Algorithm in project tink by google.
the class JwtRsaSsaPkcs1SignKeyManagerTest method createSignVerifyRaw_withDifferentHeaders.
@Test
public void createSignVerifyRaw_withDifferentHeaders() throws Exception {
if (TestUtil.isTsan()) {
// We do not use assume because Theories expects to find something which is not skipped.
return;
}
KeyTemplate template = KeyTemplates.get("JWT_RS256_2048_F4_RAW");
KeysetHandle handle = KeysetHandle.generateNew(template);
Keyset keyset = CleartextKeysetHandle.getKeyset(handle);
JwtRsaSsaPkcs1PrivateKey keyProto = JwtRsaSsaPkcs1PrivateKey.parseFrom(keyset.getKey(0).getKeyData().getValue(), ExtensionRegistryLite.getEmptyRegistry());
RSAPrivateCrtKey privateKey = createPrivateKey(keyProto);
JwtRsaSsaPkcs1Algorithm algorithm = keyProto.getPublicKey().getAlgorithm();
Enums.HashType hash = JwtRsaSsaPkcs1VerifyKeyManager.hashForPkcs1Algorithm(algorithm);
RsaSsaPkcs1SignJce rawSigner = new RsaSsaPkcs1SignJce(privateKey, hash);
JwtPublicKeyVerify verifier = handle.getPublicKeysetHandle().getPrimitive(JwtPublicKeyVerify.class);
JwtValidator validator = JwtValidator.newBuilder().allowMissingExpiration().build();
JsonObject payload = new JsonObject();
payload.addProperty("jti", "jwtId");
// valid token, with "typ" set in the header
JsonObject goodHeader = new JsonObject();
goodHeader.addProperty("alg", "RS256");
goodHeader.addProperty("typ", "typeHeader");
String goodSignedCompact = generateSignedCompact(rawSigner, goodHeader, payload);
verifier.verifyAndDecode(goodSignedCompact, JwtValidator.newBuilder().expectTypeHeader("typeHeader").allowMissingExpiration().build());
// invalid token with an empty header
JsonObject emptyHeader = new JsonObject();
String emptyHeaderSignedCompact = generateSignedCompact(rawSigner, emptyHeader, payload);
assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(emptyHeaderSignedCompact, validator));
// invalid token with an unknown algorithm in the header
JsonObject badAlgoHeader = new JsonObject();
badAlgoHeader.addProperty("alg", "RS255");
String badAlgoSignedCompact = generateSignedCompact(rawSigner, badAlgoHeader, payload);
assertThrows(GeneralSecurityException.class, () -> verifier.verifyAndDecode(badAlgoSignedCompact, validator));
// token with an unknown "kid" in the header is valid
JsonObject unknownKidHeader = new JsonObject();
unknownKidHeader.addProperty("alg", "RS256");
unknownKidHeader.addProperty("kid", "unknown");
String unknownKidSignedCompact = generateSignedCompact(rawSigner, unknownKidHeader, payload);
verifier.verifyAndDecode(unknownKidSignedCompact, validator);
}
Aggregations