add key pair as return value in PrivateKeyReader

This commit is contained in:
Jörg Prante 2022-11-16 23:15:49 +01:00
parent 808c4354ff
commit 5d788ff327
4 changed files with 89 additions and 11 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib group = org.xbib
name = net name = net
version = 3.0.1 version = 3.0.2
org.gradle.warning.mode = ALL org.gradle.warning.mode = ALL

View file

@ -1,8 +1,13 @@
package org.xbib.net.security; package org.xbib.net.security;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.spec.KeySpec;
import org.xbib.net.security.eddsa.EdDSAPrivateKey; import org.xbib.net.security.eddsa.EdDSAPrivateKey;
import org.xbib.net.security.eddsa.EdDSAPublicKey;
import org.xbib.net.security.eddsa.spec.EdDSANamedCurveTable; import org.xbib.net.security.eddsa.spec.EdDSANamedCurveTable;
import org.xbib.net.security.eddsa.spec.EdDSAPrivateKeySpec; import org.xbib.net.security.eddsa.spec.EdDSAPrivateKeySpec;
import org.xbib.net.security.eddsa.spec.EdDSAPublicKeySpec;
import org.xbib.net.security.util.Asn1Object; import org.xbib.net.security.util.Asn1Object;
import org.xbib.net.security.util.DerParser; import org.xbib.net.security.util.DerParser;
import org.xbib.net.security.util.DerUtils; import org.xbib.net.security.util.DerUtils;
@ -73,35 +78,87 @@ public class PrivateKeyReader {
public PrivateKeyReader() { public PrivateKeyReader() {
} }
public PrivateKey readPrivateKey(InputStream inputStream, String password) public KeySpec parse(InputStream inputStream, String password)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, throws IOException, NoSuchAlgorithmException, InvalidKeySpecException,
InvalidAlgorithmParameterException, NoSuchPaddingException, InvalidKeyException { InvalidAlgorithmParameterException, NoSuchPaddingException, InvalidKeyException {
Objects.requireNonNull(inputStream); Objects.requireNonNull(inputStream);
byte[] key = inputStream.readAllBytes(); byte[] key = inputStream.readAllBytes();
if (indexOf(key, BEGIN_PRIVATE_KEY,0, key.length) >= 0) { if (indexOf(key, BEGIN_PRIVATE_KEY,0, key.length) >= 0) {
byte[] keyBytes = extract(key, BEGIN_PRIVATE_KEY, END_PRIVATE_KEY); byte[] keyBytes = extract(key, BEGIN_PRIVATE_KEY, END_PRIVATE_KEY);
EncodedKeySpec keySpec = generateKeySpec(keyBytes, password != null ? password.toCharArray() : null); return generateKeySpec(keyBytes, password != null ? password.toCharArray() : null);
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
} }
if (indexOf(key, BEGIN_RSA_PRIVATE_KEY,0, key.length) >= 0) { if (indexOf(key, BEGIN_RSA_PRIVATE_KEY,0, key.length) >= 0) {
byte[] keyBytes = extract(key, BEGIN_RSA_PRIVATE_KEY, END_RSA_PRIVATE_KEY); byte[] keyBytes = extract(key, BEGIN_RSA_PRIVATE_KEY, END_RSA_PRIVATE_KEY);
RSAPrivateCrtKeySpec keySpec = getRSAKeySpec(keyBytes); return getRSAKeySpec(keyBytes);
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
} }
if (indexOf(key, BEGIN_DSA_PRIVATE_KEY,0, key.length) >= 0) { if (indexOf(key, BEGIN_DSA_PRIVATE_KEY,0, key.length) >= 0) {
byte[] keyBytes = extract(key, BEGIN_DSA_PRIVATE_KEY, END_DSA_PRIVATE_KEY); byte[] keyBytes = extract(key, BEGIN_DSA_PRIVATE_KEY, END_DSA_PRIVATE_KEY);
DSAPrivateKeySpec keySpec = getDSAKeySpec(keyBytes); return getDSAKeySpec(keyBytes);
return KeyFactory.getInstance("DSA").generatePrivate(keySpec);
} }
if (indexOf(key, BEGIN_EC_PRIVATE_KEY,0, key.length) >= 0) { if (indexOf(key, BEGIN_EC_PRIVATE_KEY,0, key.length) >= 0) {
byte[] keyBytes = extract(key, BEGIN_EC_PRIVATE_KEY, END_EC_PRIVATE_KEY); byte[] keyBytes = extract(key, BEGIN_EC_PRIVATE_KEY, END_EC_PRIVATE_KEY);
ECPrivateKeySpec keySpec = getECKeySpec(keyBytes); return getECKeySpec(keyBytes);
return KeyFactory.getInstance("EC").generatePrivate(keySpec);
} }
if (indexOf(key, BEGIN_OPENSSH_PRIVATE_KEY,0, key.length) >= 0) { if (indexOf(key, BEGIN_OPENSSH_PRIVATE_KEY,0, key.length) >= 0) {
byte[] keyBytes = extract(key, BEGIN_OPENSSH_PRIVATE_KEY, END_OPENSSH_PRIVATE_KEY); byte[] keyBytes = extract(key, BEGIN_OPENSSH_PRIVATE_KEY, END_OPENSSH_PRIVATE_KEY);
byte[] sk = Arrays.copyOfRange(keyBytes, 0, 32); byte[] sk = Arrays.copyOfRange(keyBytes, 0, 32);
return new EdDSAPrivateKey(new EdDSAPrivateKeySpec(sk, EdDSANamedCurveTable.getByName("Ed25519"))); return new EdDSAPrivateKeySpec(sk, EdDSANamedCurveTable.getByName("Ed25519"));
}
throw new IOException("invalid PEM input stream");
}
public PrivateKey readPrivateKey(InputStream inputStream, String password)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException,
InvalidAlgorithmParameterException, NoSuchPaddingException, InvalidKeyException {
KeySpec keySpec = parse(inputStream, password);
if (keySpec instanceof EncodedKeySpec) {
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
}
if (keySpec instanceof RSAPrivateCrtKeySpec) {
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
}
if (keySpec instanceof DSAPrivateKeySpec) {
return KeyFactory.getInstance("DSA").generatePrivate(keySpec);
}
if (keySpec instanceof ECPrivateKeySpec) {
return KeyFactory.getInstance("EC").generatePrivate(keySpec);
}
if (keySpec instanceof EdDSAPrivateKeySpec) {
return new EdDSAPrivateKey((EdDSAPrivateKeySpec) keySpec);
}
throw new IOException("invalid PEM");
}
public KeyPair generateFrom(InputStream inputStream, String password)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException,
InvalidAlgorithmParameterException, NoSuchPaddingException, InvalidKeyException {
KeySpec keySpec = parse(inputStream, password);
PrivateKey privateKey = null;
PublicKey publicKey = null;
if (keySpec instanceof EncodedKeySpec) {
privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
}
if (keySpec instanceof RSAPrivateCrtKeySpec) {
privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
}
if (keySpec instanceof DSAPrivateKeySpec) {
privateKey = KeyFactory.getInstance("DSA").generatePrivate(keySpec);
publicKey = KeyFactory.getInstance("DSA").generatePublic(keySpec);
}
if (keySpec instanceof ECPrivateKeySpec) {
privateKey = KeyFactory.getInstance("EC").generatePrivate(keySpec);
publicKey = KeyFactory.getInstance("EC").generatePublic(keySpec);
}
if (keySpec instanceof EdDSAPrivateKeySpec) {
EdDSAPrivateKeySpec privateKeySpec = (EdDSAPrivateKeySpec) keySpec;
privateKey = new EdDSAPrivateKey(privateKeySpec);
EdDSAPublicKeySpec publicKeySpec = new EdDSAPublicKeySpec(privateKeySpec.getA(), privateKeySpec.getParams());
publicKey = new EdDSAPublicKey(publicKeySpec);
}
if (publicKey != null && privateKey != null) {
return new KeyPair(publicKey, privateKey);
} }
throw new IOException("invalid PEM"); throw new IOException("invalid PEM");
} }

View file

@ -8,6 +8,7 @@ import java.nio.charset.StandardCharsets;
import java.security.PrivateKey; import java.security.PrivateKey;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class PrivateKeyReaderTest { public class PrivateKeyReaderTest {

View file

@ -0,0 +1,20 @@
package org.xbib.net.security.ed25519;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;
import org.junit.jupiter.api.Test;
public class Ed25519KeyTest {
@Test
public void generate() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
Signature sig = Signature.getInstance("Ed25519");
sig.initSign(kp.getPrivate());
sig.update("Hello Jörg".getBytes(StandardCharsets.UTF_8));
byte[] s = sig.sign();
}
}