backend/src/main/java/de/tavolio/realm/key/KeypairService.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;
}
}