Introduce JwtEncoder with JWS implementation
Closes gh-81
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.crypto.keys;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.spec.ECFieldFp;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.ECPoint;
|
||||
import java.security.spec.EllipticCurve;
|
||||
|
||||
/**
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.1
|
||||
*/
|
||||
final class KeyGeneratorUtils {
|
||||
|
||||
static SecretKey generateSecretKey() {
|
||||
SecretKey hmacKey;
|
||||
try {
|
||||
hmacKey = KeyGenerator.getInstance("HmacSha256").generateKey();
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
return hmacKey;
|
||||
}
|
||||
|
||||
static KeyPair generateRsaKey() {
|
||||
KeyPair keyPair;
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(2048);
|
||||
keyPair = keyPairGenerator.generateKeyPair();
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
static KeyPair generateEcKey() {
|
||||
EllipticCurve ellipticCurve = new EllipticCurve(
|
||||
new ECFieldFp(
|
||||
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951")),
|
||||
new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853948"),
|
||||
new BigInteger("41058363725152142129326129780047268409114441015993725554835256314039467401291"));
|
||||
ECPoint ecPoint = new ECPoint(
|
||||
new BigInteger("48439561293906451759052585252797914202762949526041747995844080717082404635286"),
|
||||
new BigInteger("36134250956749795798585127919587881956611106672985015071877198253568414405109"));
|
||||
ECParameterSpec ecParameterSpec = new ECParameterSpec(
|
||||
ellipticCurve,
|
||||
ecPoint,
|
||||
new BigInteger("115792089210356248762697446949407573529996955224135760342422259061068512044369"),
|
||||
1);
|
||||
|
||||
KeyPair keyPair;
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
|
||||
keyPairGenerator.initialize(ecParameterSpec);
|
||||
keyPair = keyPairGenerator.generateKeyPair();
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
return keyPair;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.crypto.keys;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Implementations of this interface are responsible for the management of {@link ManagedKey}(s),
|
||||
* e.g. {@code javax.crypto.SecretKey}, {@code java.security.PrivateKey}, {@code java.security.PublicKey}, etc.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.1
|
||||
* @see ManagedKey
|
||||
*/
|
||||
public interface KeyManager {
|
||||
|
||||
/**
|
||||
* Returns the {@link ManagedKey} identified by the provided {@code keyId},
|
||||
* or {@code null} if not found.
|
||||
*
|
||||
* @param keyId the key ID
|
||||
* @return the {@link ManagedKey}, or {@code null} if not found
|
||||
*/
|
||||
@Nullable
|
||||
ManagedKey findByKeyId(String keyId);
|
||||
|
||||
/**
|
||||
* Returns a {@code Set} of {@link ManagedKey}(s) having the provided key {@code algorithm},
|
||||
* or an empty {@code Set} if not found.
|
||||
*
|
||||
* @param algorithm the key algorithm
|
||||
* @return a {@code Set} of {@link ManagedKey}(s), or an empty {@code Set} if not found
|
||||
*/
|
||||
Set<ManagedKey> findByAlgorithm(String algorithm);
|
||||
|
||||
/**
|
||||
* Returns a {@code Set} of the {@link ManagedKey}(s).
|
||||
*
|
||||
* @return a {@code Set} of the {@link ManagedKey}(s)
|
||||
*/
|
||||
Set<ManagedKey> getKeys();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.crypto.keys;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.security.core.SpringSecurityCoreVersion2;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.io.Serializable;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A {@code java.security.Key} that is managed by a {@link KeyManager}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.1
|
||||
* @see KeyManager
|
||||
*/
|
||||
public final class ManagedKey implements Serializable {
|
||||
private static final long serialVersionUID = SpringSecurityCoreVersion2.SERIAL_VERSION_UID;
|
||||
private Key key;
|
||||
private PublicKey publicKey;
|
||||
private String keyId;
|
||||
private Instant activatedOn;
|
||||
private Instant deactivatedOn;
|
||||
|
||||
private ManagedKey() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this is a symmetric key, {@code false} otherwise.
|
||||
*
|
||||
* @return {@code true} if this is a symmetric key, {@code false} otherwise
|
||||
*/
|
||||
public boolean isSymmetric() {
|
||||
return SecretKey.class.isAssignableFrom(this.key.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this is a asymmetric key, {@code false} otherwise.
|
||||
*
|
||||
* @return {@code true} if this is a asymmetric key, {@code false} otherwise
|
||||
*/
|
||||
public boolean isAsymmetric() {
|
||||
return PrivateKey.class.isAssignableFrom(this.key.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type of {@code java.security.Key},
|
||||
* e.g. {@code javax.crypto.SecretKey} or {@code java.security.PrivateKey}.
|
||||
*
|
||||
* @param <T> the type of {@code java.security.Key}
|
||||
* @return the type of {@code java.security.Key}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Key> T getKey() {
|
||||
return (T) this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code java.security.PublicKey} if this is a asymmetric key, {@code null} otherwise.
|
||||
*
|
||||
* @return the {@code java.security.PublicKey} if this is a asymmetric key, {@code null} otherwise
|
||||
*/
|
||||
@Nullable
|
||||
public PublicKey getPublicKey() {
|
||||
return this.publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key ID.
|
||||
*
|
||||
* @return the key ID
|
||||
*/
|
||||
public String getKeyId() {
|
||||
return this.keyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time when this key was activated.
|
||||
*
|
||||
* @return the time when this key was activated
|
||||
*/
|
||||
public Instant getActivatedOn() {
|
||||
return this.activatedOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time when this key was deactivated, {@code null} if still active.
|
||||
*
|
||||
* @return the time when this key was deactivated, {@code null} if still active
|
||||
*/
|
||||
@Nullable
|
||||
public Instant getDeactivatedOn() {
|
||||
return this.deactivatedOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this key is active, {@code false} otherwise.
|
||||
*
|
||||
* @return {@code true} if this key is active, {@code false} otherwise
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return getDeactivatedOn() == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key algorithm.
|
||||
*
|
||||
* @return the key algorithm
|
||||
*/
|
||||
public String getAlgorithm() {
|
||||
return this.key.getAlgorithm();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ManagedKey that = (ManagedKey) obj;
|
||||
return Objects.equals(this.keyId, that.keyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.keyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link Builder}, initialized with the provided {@code javax.crypto.SecretKey}.
|
||||
*
|
||||
* @param secretKey the {@code javax.crypto.SecretKey}
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public static Builder withSymmetricKey(SecretKey secretKey) {
|
||||
return new Builder(secretKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link Builder}, initialized with the provided
|
||||
* {@code java.security.PublicKey} and {@code java.security.PrivateKey}.
|
||||
*
|
||||
* @param publicKey the {@code java.security.PublicKey}
|
||||
* @param privateKey the {@code java.security.PrivateKey}
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public static Builder withAsymmetricKey(PublicKey publicKey, PrivateKey privateKey) {
|
||||
return new Builder(publicKey, privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for {@link ManagedKey}.
|
||||
*/
|
||||
public static class Builder {
|
||||
private Key key;
|
||||
private PublicKey publicKey;
|
||||
private String keyId;
|
||||
private Instant activatedOn;
|
||||
private Instant deactivatedOn;
|
||||
|
||||
private Builder(SecretKey secretKey) {
|
||||
Assert.notNull(secretKey, "secretKey cannot be null");
|
||||
this.key = secretKey;
|
||||
}
|
||||
|
||||
private Builder(PublicKey publicKey, PrivateKey privateKey) {
|
||||
Assert.notNull(publicKey, "publicKey cannot be null");
|
||||
Assert.notNull(privateKey, "privateKey cannot be null");
|
||||
this.key = privateKey;
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key ID.
|
||||
*
|
||||
* @param keyId the key ID
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public Builder keyId(String keyId) {
|
||||
this.keyId = keyId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time when this key was activated.
|
||||
*
|
||||
* @param activatedOn the time when this key was activated
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public Builder activatedOn(Instant activatedOn) {
|
||||
this.activatedOn = activatedOn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time when this key was deactivated.
|
||||
*
|
||||
* @param deactivatedOn the time when this key was deactivated
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public Builder deactivatedOn(Instant deactivatedOn) {
|
||||
this.deactivatedOn = deactivatedOn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new {@link ManagedKey}.
|
||||
*
|
||||
* @return a {@link ManagedKey}
|
||||
*/
|
||||
public ManagedKey build() {
|
||||
Assert.hasText(this.keyId, "keyId cannot be empty");
|
||||
Assert.notNull(this.activatedOn, "activatedOn cannot be null");
|
||||
|
||||
ManagedKey managedKey = new ManagedKey();
|
||||
managedKey.key = this.key;
|
||||
managedKey.publicKey = this.publicKey;
|
||||
managedKey.keyId = this.keyId;
|
||||
managedKey.activatedOn = this.activatedOn;
|
||||
managedKey.deactivatedOn = this.deactivatedOn;
|
||||
return managedKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.crypto.keys;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.KeyPair;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateRsaKey;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateSecretKey;
|
||||
|
||||
/**
|
||||
* An implementation of a {@link KeyManager} that generates the {@link ManagedKey}(s) when constructed.
|
||||
*
|
||||
* <p>
|
||||
* <b>NOTE:</b> This implementation should ONLY be used during development/testing.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.1
|
||||
* @see KeyManager
|
||||
*/
|
||||
public final class StaticKeyGeneratingKeyManager implements KeyManager {
|
||||
private final Map<String, ManagedKey> keys;
|
||||
|
||||
public StaticKeyGeneratingKeyManager() {
|
||||
this.keys = Collections.unmodifiableMap(new HashMap<>(generateKeys()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ManagedKey findByKeyId(String keyId) {
|
||||
Assert.hasText(keyId, "keyId cannot be empty");
|
||||
return this.keys.get(keyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ManagedKey> findByAlgorithm(String algorithm) {
|
||||
Assert.hasText(algorithm, "algorithm cannot be empty");
|
||||
return this.keys.values().stream()
|
||||
.filter(managedKey -> managedKey.getAlgorithm().equals(algorithm))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ManagedKey> getKeys() {
|
||||
return new HashSet<>(this.keys.values());
|
||||
}
|
||||
|
||||
private static Map<String, ManagedKey> generateKeys() {
|
||||
KeyPair rsaKeyPair = generateRsaKey();
|
||||
ManagedKey rsaManagedKey = ManagedKey.withAsymmetricKey(rsaKeyPair.getPublic(), rsaKeyPair.getPrivate())
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now())
|
||||
.build();
|
||||
|
||||
SecretKey hmacKey = generateSecretKey();
|
||||
ManagedKey secretManagedKey = ManagedKey.withSymmetricKey(hmacKey)
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now())
|
||||
.build();
|
||||
|
||||
return Stream.of(rsaManagedKey, secretManagedKey)
|
||||
.collect(Collectors.toMap(ManagedKey::getKeyId, v -> v));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.crypto.keys;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.security.Key;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PrivateKey;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateRsaKey;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateSecretKey;
|
||||
|
||||
/**
|
||||
* Tests for {@link ManagedKey}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class ManagedKeyTests {
|
||||
private static SecretKey secretKey;
|
||||
private static KeyPair rsaKeyPair;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
secretKey = generateSecretKey();
|
||||
rsaKeyPair = generateRsaKey();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withSymmetricKeyWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withSymmetricKey(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("secretKey cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenKeyIdNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withSymmetricKey(secretKey).build())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("keyId cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenActivatedOnNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withSymmetricKey(secretKey).keyId("keyId").build())
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("activatedOn cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenSymmetricKeyAllAttributesProvidedThenAllAttributesAreSet() {
|
||||
ManagedKey expectedManagedKey = TestManagedKeys.secretManagedKey().build();
|
||||
|
||||
ManagedKey managedKey = ManagedKey.withSymmetricKey(expectedManagedKey.getKey())
|
||||
.keyId(expectedManagedKey.getKeyId())
|
||||
.activatedOn(expectedManagedKey.getActivatedOn())
|
||||
.build();
|
||||
|
||||
assertThat(managedKey.isSymmetric()).isTrue();
|
||||
assertThat(managedKey.<Key>getKey()).isInstanceOf(SecretKey.class);
|
||||
assertThat(managedKey.<SecretKey>getKey()).isEqualTo(expectedManagedKey.getKey());
|
||||
assertThat(managedKey.getPublicKey()).isNull();
|
||||
assertThat(managedKey.getKeyId()).isEqualTo(expectedManagedKey.getKeyId());
|
||||
assertThat(managedKey.getActivatedOn()).isEqualTo(expectedManagedKey.getActivatedOn());
|
||||
assertThat(managedKey.getDeactivatedOn()).isEqualTo(expectedManagedKey.getDeactivatedOn());
|
||||
assertThat(managedKey.isActive()).isTrue();
|
||||
assertThat(managedKey.getAlgorithm()).isEqualTo(expectedManagedKey.getAlgorithm());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAsymmetricKeyWhenPublicKeyNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withAsymmetricKey(null, rsaKeyPair.getPrivate()))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("publicKey cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAsymmetricKeyWhenPrivateKeyNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> ManagedKey.withAsymmetricKey(rsaKeyPair.getPublic(), null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("privateKey cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenAsymmetricKeyAllAttributesProvidedThenAllAttributesAreSet() {
|
||||
ManagedKey expectedManagedKey = TestManagedKeys.rsaManagedKey().build();
|
||||
|
||||
ManagedKey managedKey = ManagedKey.withAsymmetricKey(expectedManagedKey.getPublicKey(), expectedManagedKey.getKey())
|
||||
.keyId(expectedManagedKey.getKeyId())
|
||||
.activatedOn(expectedManagedKey.getActivatedOn())
|
||||
.build();
|
||||
|
||||
assertThat(managedKey.isAsymmetric()).isTrue();
|
||||
assertThat(managedKey.<Key>getKey()).isInstanceOf(PrivateKey.class);
|
||||
assertThat(managedKey.<PrivateKey>getKey()).isEqualTo(expectedManagedKey.getKey());
|
||||
assertThat(managedKey.getPublicKey()).isNotNull();
|
||||
assertThat(managedKey.getKeyId()).isEqualTo(expectedManagedKey.getKeyId());
|
||||
assertThat(managedKey.getActivatedOn()).isEqualTo(expectedManagedKey.getActivatedOn());
|
||||
assertThat(managedKey.getDeactivatedOn()).isEqualTo(expectedManagedKey.getDeactivatedOn());
|
||||
assertThat(managedKey.isActive()).isTrue();
|
||||
assertThat(managedKey.getAlgorithm()).isEqualTo(expectedManagedKey.getAlgorithm());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.crypto.keys;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateEcKey;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateRsaKey;
|
||||
import static org.springframework.security.crypto.keys.KeyGeneratorUtils.generateSecretKey;
|
||||
|
||||
/**
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class TestManagedKeys {
|
||||
|
||||
public static ManagedKey.Builder secretManagedKey() {
|
||||
return ManagedKey.withSymmetricKey(generateSecretKey())
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now());
|
||||
}
|
||||
|
||||
public static ManagedKey.Builder rsaManagedKey() {
|
||||
KeyPair rsaKeyPair = generateRsaKey();
|
||||
return ManagedKey.withAsymmetricKey(rsaKeyPair.getPublic(), rsaKeyPair.getPrivate())
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now());
|
||||
}
|
||||
|
||||
public static ManagedKey.Builder ecManagedKey() {
|
||||
KeyPair ecKeyPair = generateEcKey();
|
||||
return ManagedKey.withAsymmetricKey(ecKeyPair.getPublic(), ecKeyPair.getPrivate())
|
||||
.keyId(UUID.randomUUID().toString())
|
||||
.activatedOn(Instant.now());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user