83 lines
2.4 KiB
Java
83 lines
2.4 KiB
Java
package de.tavolio.realm.key;
|
|
|
|
import de.tavolio.realm.RealmEntity;
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.transaction.Transactional;
|
|
|
|
import java.security.KeyPair;
|
|
import java.security.KeyPairGenerator;
|
|
import java.security.interfaces.ECPublicKey;
|
|
import java.security.spec.ECGenParameterSpec;
|
|
import java.util.Base64;
|
|
import java.util.NoSuchElementException;
|
|
import java.util.UUID;
|
|
|
|
@ApplicationScoped
|
|
public class KeypairService
|
|
{
|
|
public static final String EC = "EC";
|
|
public static final String P256 = "secp256r1";
|
|
|
|
@Inject
|
|
KeypairRepo keypairRepo;
|
|
|
|
@Transactional
|
|
public void create(RealmEntity realm, String type, String alg)
|
|
{
|
|
if ("EC".equals(type))
|
|
{
|
|
KeypairEntity keypair = getKeypair(realm);
|
|
keypair.setRealm(realm);
|
|
realm.getKeys().add(keypair);
|
|
keypairRepo.persist(keypair);
|
|
return;
|
|
}
|
|
throw new NoSuchElementException();
|
|
}
|
|
|
|
|
|
private KeypairEntity getKeypair(RealmEntity realm)
|
|
{
|
|
KeyPair pair = generate();
|
|
ECPublicKey publicKey = (ECPublicKey) pair.getPublic();
|
|
byte[] xBytes = toFixedLength(publicKey.getW().getAffineX().toByteArray());
|
|
byte[] yBytes = toFixedLength(publicKey.getW().getAffineY().toByteArray());
|
|
return new KeypairEntity()
|
|
.setId(UUID.randomUUID().toString())
|
|
.setRealm(realm)
|
|
.setPrivateKey(pair.getPrivate().getEncoded())
|
|
.setType("EC")
|
|
.setUse("sig")
|
|
.setAlg("ES256")
|
|
.setCrv("P-256")
|
|
.setX(Base64.getUrlEncoder().withoutPadding().encodeToString(xBytes))
|
|
.setY(Base64.getUrlEncoder().withoutPadding().encodeToString(yBytes));
|
|
}
|
|
|
|
private KeyPair generate()
|
|
{
|
|
try
|
|
{
|
|
KeyPairGenerator generator = KeyPairGenerator.getInstance(EC);
|
|
generator.initialize(new ECGenParameterSpec(P256));
|
|
return generator.generateKeyPair();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new RuntimeException();
|
|
}
|
|
}
|
|
|
|
private byte[] toFixedLength(byte[] input)
|
|
{
|
|
if (input.length > 32)
|
|
{
|
|
byte[] result = new byte[32];
|
|
System.arraycopy(input, input.length - 32, result, 0, 32);
|
|
return result;
|
|
}
|
|
return input;
|
|
}
|
|
}
|