KeyFactory and KeyPairGenerator for ElGamal.

Stub out decoding key constructors.
This commit is contained in:
zzz
2016-01-23 17:12:47 +00:00
parent e276febf0a
commit c9063f9d9b
6 changed files with 215 additions and 12 deletions

View File

@ -79,6 +79,11 @@ public class CryptoConstants {
*/
public static final DSAParameterSpec DSA_SHA1_SPEC = new DSAParameterSpec(dsap, dsaq, dsag);
/**
* @since 0.9.25
*/
public static final ElGamalParameterSpec I2P_ELGAMAL_2048_SPEC = new ElGamalParameterSpec(elgp, elgg);
/**
* This will be org.bouncycastle.jce.spec.ElgamalParameterSpec
* if BC is available, otherwise it
@ -99,11 +104,11 @@ public class CryptoConstants {
} catch (Exception e) {
//System.out.println("BC ElG spec failed");
//e.printStackTrace();
spec = new ElGamalParameterSpec(elgp, elgg);
spec = I2P_ELGAMAL_2048_SPEC;
}
} else {
//System.out.println("BC not available");
spec = new ElGamalParameterSpec(elgp, elgg);
spec = I2P_ELGAMAL_2048_SPEC;
}
ELGAMAL_2048_SPEC = spec;
}

View File

@ -27,7 +27,7 @@ public enum EncType {
* This is the default.
* Pubkey 256 bytes, privkey 256 bytes.
*/
ELGAMAL_2048(0, 256, 256, EncAlgo.ELGAMAL, "ElGamal/None/NoPadding", CryptoConstants.ELGAMAL_2048_SPEC, "0"),
ELGAMAL_2048(0, 256, 256, EncAlgo.ELGAMAL, "ElGamal/None/NoPadding", CryptoConstants.I2P_ELGAMAL_2048_SPEC, "0"),
/** Pubkey 64 bytes; privkey 32 bytes; */
EC_P256(1, 64, 32, EncAlgo.EC, "EC/None/NoPadding", ECConstants.P256_SPEC, "0.9.20"),

View File

@ -0,0 +1,88 @@
package net.i2p.crypto.elgamal;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.spec.DHParameterSpec;
import static net.i2p.crypto.CryptoConstants.I2P_ELGAMAL_2048_SPEC;
import net.i2p.crypto.elgamal.impl.ElGamalPrivateKeyImpl;
import net.i2p.crypto.elgamal.impl.ElGamalPrivateKeyImpl;
import net.i2p.crypto.elgamal.impl.ElGamalPublicKeyImpl;
import net.i2p.crypto.elgamal.spec.ElGamalParameterSpec;
import net.i2p.crypto.elgamal.spec.ElGamalPrivateKeySpec;
import net.i2p.crypto.elgamal.spec.ElGamalPublicKeySpec;
/**
* Modified from eddsa
*
* @since 0.9.25
*/
public class KeyFactory extends KeyFactorySpi {
/**
* Supports PKCS8EncodedKeySpec
*/
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
if (keySpec instanceof ElGamalPrivateKeySpec) {
return new ElGamalPrivateKeyImpl((ElGamalPrivateKeySpec) keySpec);
}
if (keySpec instanceof PKCS8EncodedKeySpec) {
return new ElGamalPrivateKeyImpl((PKCS8EncodedKeySpec) keySpec);
}
throw new InvalidKeySpecException("key spec not recognised");
}
/**
* Supports X509EncodedKeySpec
*/
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException {
if (keySpec instanceof ElGamalPublicKeySpec) {
return new ElGamalPublicKeyImpl((ElGamalPublicKeySpec) keySpec);
}
if (keySpec instanceof X509EncodedKeySpec) {
return new ElGamalPublicKeyImpl((X509EncodedKeySpec) keySpec);
}
throw new InvalidKeySpecException("key spec not recognised");
}
@SuppressWarnings("unchecked")
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
throws InvalidKeySpecException {
if (keySpec.isAssignableFrom(ElGamalPublicKeySpec.class) && key instanceof ElGamalPublicKey) {
ElGamalPublicKey k = (ElGamalPublicKey) key;
// key.getParams() is a DHParameterSpec
DHParameterSpec dhp = k.getParams();
if (dhp != null) {
if (dhp.getP().equals(I2P_ELGAMAL_2048_SPEC.getP()) &&
dhp.getG().equals(I2P_ELGAMAL_2048_SPEC.getG()))
return (T) new ElGamalPrivateKeySpec(k.getY(), I2P_ELGAMAL_2048_SPEC);
return (T) new ElGamalPrivateKeySpec(k.getY(), new ElGamalParameterSpec(dhp.getP(), dhp.getG()));
}
} else if (keySpec.isAssignableFrom(ElGamalPrivateKeySpec.class) && key instanceof ElGamalPrivateKey) {
ElGamalPrivateKey k = (ElGamalPrivateKey) key;
// key.getParams() is a DHParameterSpec
DHParameterSpec dhp = k.getParams();
if (dhp != null) {
if (dhp.getP().equals(I2P_ELGAMAL_2048_SPEC.getP()) &&
dhp.getG().equals(I2P_ELGAMAL_2048_SPEC.getG()))
return (T) new ElGamalPrivateKeySpec(k.getX(), I2P_ELGAMAL_2048_SPEC);
return (T) new ElGamalPrivateKeySpec(k.getX(), new ElGamalParameterSpec(dhp.getP(), dhp.getG()));
}
}
throw new InvalidKeySpecException("not implemented yet " + key + " " + keySpec);
}
protected Key engineTranslateKey(Key key) throws InvalidKeyException {
throw new InvalidKeyException("No other ElGamal key providers known");
}
}

View File

@ -0,0 +1,84 @@
package net.i2p.crypto.elgamal;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.KeyPair;
import java.security.KeyPairGeneratorSpi;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import static net.i2p.crypto.CryptoConstants.I2P_ELGAMAL_2048_SPEC;
import net.i2p.crypto.KeyGenerator;
import net.i2p.crypto.elgamal.impl.ElGamalPrivateKeyImpl;
import net.i2p.crypto.elgamal.impl.ElGamalPublicKeyImpl;
import net.i2p.crypto.elgamal.spec.ElGamalGenParameterSpec;
import net.i2p.crypto.elgamal.spec.ElGamalParameterSpec;
import net.i2p.crypto.elgamal.spec.ElGamalPrivateKeySpec;
import net.i2p.crypto.elgamal.spec.ElGamalPublicKeySpec;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.data.SimpleDataStructure;
import net.i2p.util.NativeBigInteger;
import net.i2p.util.RandomSource;
/**
* Modified from eddsa
* Only supported strength is 2048
*
* @since 0.9.25
*/
public class KeyPairGenerator extends KeyPairGeneratorSpi {
// always long, don't use short key
private static final int DEFAULT_STRENGTH = 2048;
private ElGamalParameterSpec elgParams;
//private SecureRandom random;
private boolean initialized;
/**
* @param strength must be 2048
* @param random ignored
*/
public void initialize(int strength, SecureRandom random) {
if (strength != DEFAULT_STRENGTH)
throw new InvalidParameterException("unknown key type.");
elgParams = I2P_ELGAMAL_2048_SPEC;
try {
initialize(elgParams, random);
} catch (InvalidAlgorithmParameterException e) {
throw new InvalidParameterException("key type not configurable.");
}
}
/**
* @param random ignored
*/
@Override
public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
if (params instanceof ElGamalParameterSpec) {
elgParams = (ElGamalParameterSpec) params;
if (!elgParams.equals(I2P_ELGAMAL_2048_SPEC))
throw new InvalidAlgorithmParameterException("unsupported ElGamalParameterSpec");
} else if (params instanceof ElGamalGenParameterSpec) {
ElGamalGenParameterSpec elgGPS = (ElGamalGenParameterSpec) params;
if (elgGPS.getPrimeSize() != DEFAULT_STRENGTH)
throw new InvalidAlgorithmParameterException("unsupported prime size");
elgParams = I2P_ELGAMAL_2048_SPEC;
} else {
throw new InvalidAlgorithmParameterException("parameter object not a ElGamalParameterSpec");
}
//this.random = random;
initialized = true;
}
public KeyPair generateKeyPair() {
if (!initialized)
initialize(DEFAULT_STRENGTH, RandomSource.getInstance());
KeyGenerator kg = KeyGenerator.getInstance();
SimpleDataStructure[] keys = kg.generatePKIKeys();
PublicKey pubKey = (PublicKey) keys[0];
PrivateKey privKey = (PrivateKey) keys[1];
ElGamalPublicKey epubKey = new ElGamalPublicKeyImpl(new NativeBigInteger(1, pubKey.getData()), elgParams);
ElGamalPrivateKey eprivKey = new ElGamalPrivateKeyImpl(new NativeBigInteger(1, privKey.getData()), elgParams);
return new KeyPair(epubKey, eprivKey);
}
}

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.spec.PKCS8EncodedKeySpec;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.spec.DHParameterSpec;
@ -25,34 +26,50 @@ public class ElGamalPrivateKeyImpl
{
}
ElGamalPrivateKeyImpl(
public ElGamalPrivateKeyImpl(
ElGamalPrivateKey key)
{
this.x = key.getX();
this.elSpec = key.getParameters();
}
ElGamalPrivateKeyImpl(
public ElGamalPrivateKeyImpl(
DHPrivateKey key)
{
this.x = key.getX();
this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG());
}
ElGamalPrivateKeyImpl(
public ElGamalPrivateKeyImpl(
ElGamalPrivateKeySpec spec)
{
this.x = spec.getX();
this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG());
}
ElGamalPrivateKeyImpl(
public ElGamalPrivateKeyImpl(
DHPrivateKeySpec spec)
{
this.x = spec.getX();
this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG());
}
public ElGamalPrivateKeyImpl(
BigInteger x,
ElGamalParameterSpec elSpec)
{
this.x = x;
this.elSpec = elSpec;
}
public ElGamalPrivateKeyImpl(
PKCS8EncodedKeySpec spec)
{
throw new UnsupportedOperationException("todo");
//this.x = spec.getX();
//this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG());
}
public String getAlgorithm()
{
return "ElGamal";

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
@ -21,41 +22,49 @@ public class ElGamalPublicKeyImpl
private BigInteger y;
private ElGamalParameterSpec elSpec;
ElGamalPublicKeyImpl(
public ElGamalPublicKeyImpl(
ElGamalPublicKeySpec spec)
{
this.y = spec.getY();
this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG());
}
ElGamalPublicKeyImpl(
public ElGamalPublicKeyImpl(
DHPublicKeySpec spec)
{
this.y = spec.getY();
this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG());
}
ElGamalPublicKeyImpl(
public ElGamalPublicKeyImpl(
ElGamalPublicKey key)
{
this.y = key.getY();
this.elSpec = key.getParameters();
}
ElGamalPublicKeyImpl(
public ElGamalPublicKeyImpl(
DHPublicKey key)
{
this.y = key.getY();
this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG());
}
ElGamalPublicKeyImpl(
public ElGamalPublicKeyImpl(
BigInteger y,
ElGamalParameterSpec elSpec)
{
this.y = y;
this.elSpec = elSpec;
}
public ElGamalPublicKeyImpl(
X509EncodedKeySpec spec)
{
throw new UnsupportedOperationException("todo");
//this.y = y;
//this.elSpec = elSpec;
}
public String getAlgorithm()
{