Skip to content

Commit 5271bb3

Browse files
committed
save this
1 parent 76b5a9c commit 5271bb3

4 files changed

Lines changed: 71 additions & 142 deletions

File tree

sdk/src/main/java/io/opentdf/platform/sdk/ECKeyPair.java

Lines changed: 57 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
package io.opentdf.platform.sdk;
22

3+
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
34
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
45
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
5-
import org.bouncycastle.cert.X509CertificateHolder;
6+
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
7+
import org.bouncycastle.asn1.x9.X962Parameters;
8+
import org.bouncycastle.asn1.x9.X9ECParameters;
9+
import org.bouncycastle.asn1.x9.X9ECPoint;
610
import org.bouncycastle.crypto.digests.SHA256Digest;
711
import org.bouncycastle.crypto.generators.HKDFBytesGenerator;
812
import org.bouncycastle.crypto.params.HKDFParameters;
913
import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi;
10-
import org.bouncycastle.jce.ECNamedCurveTable;
11-
import org.bouncycastle.jce.interfaces.ECPrivateKey;
12-
import org.bouncycastle.jce.interfaces.ECPublicKey;
14+
import org.bouncycastle.jcajce.util.ECKeyUtil;
1315
import org.bouncycastle.jce.provider.BouncyCastleProvider;
1416
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
17+
import org.bouncycastle.math.ec.ECCurve;
1518
import org.bouncycastle.math.ec.ECPoint;
16-
import org.bouncycastle.openssl.PEMException;
1719
import org.bouncycastle.openssl.PEMParser;
1820
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
21+
import org.bouncycastle.pqc.jcajce.provider.util.KeyUtil;
1922
import org.bouncycastle.util.io.pem.*;
2023
import org.bouncycastle.util.io.pem.PemReader;
21-
import org.bouncycastle.jce.spec.ECPublicKeySpec;
2224

2325
import javax.crypto.KeyAgreement;
26+
import java.security.interfaces.ECPrivateKey;
27+
import java.security.interfaces.ECPublicKey;
2428
import java.io.*;
2529
import java.security.*;
2630
import java.security.spec.*;
@@ -31,14 +35,11 @@ public class ECKeyPair {
3135
static {
3236
Security.addProvider(new BouncyCastleProvider());
3337
}
34-
3538
public enum ECAlgorithm {
3639
ECDH,
3740
ECDSA
3841
}
3942

40-
private static final BouncyCastleProvider BOUNCY_CASTLE_PROVIDER = new BouncyCastleProvider();
41-
4243
public enum NanoTDFECCurve {
4344
SECP256R1("secp256r1", KeyType.EC256Key),
4445
PRIME256V1("prime256v1", KeyType.EC256Key),
@@ -63,8 +64,9 @@ public KeyType getKeyType() {
6364
}
6465
}
6566

66-
private KeyPair keyPair;
67-
private String curveName;
67+
private final ECPrivateKey privateKey;
68+
private final ECPublicKey publicKey;
69+
private final String curveName;
6870

6971
public ECKeyPair() {
7072
this("secp256r1", ECAlgorithm.ECDH);
@@ -77,9 +79,9 @@ public ECKeyPair(String curveName, ECAlgorithm algorithm) {
7779
// Should this just use the algorithm vs use ECDH only for ECDH and ECDSA for
7880
// everything else.
7981
if (algorithm == ECAlgorithm.ECDH) {
80-
generator = KeyPairGeneratorSpi.getInstance(ECAlgorithm.ECDH.name(), BOUNCY_CASTLE_PROVIDER);
82+
generator = KeyPairGeneratorSpi.getInstance(ECAlgorithm.ECDH.name());
8183
} else {
82-
generator = KeyPairGeneratorSpi.getInstance(ECAlgorithm.ECDSA.name(), BOUNCY_CASTLE_PROVIDER);
84+
generator = KeyPairGeneratorSpi.getInstance(ECAlgorithm.ECDSA.name());
8385
}
8486
} catch (NoSuchAlgorithmException e) {
8587
throw new RuntimeException(e);
@@ -91,21 +93,24 @@ public ECKeyPair(String curveName, ECAlgorithm algorithm) {
9193
} catch (InvalidAlgorithmParameterException e) {
9294
throw new RuntimeException(e);
9395
}
94-
this.keyPair = generator.generateKeyPair();
96+
KeyPair keyPair = generator.generateKeyPair();
97+
this.publicKey = (ECPublicKey)keyPair.getPublic();
98+
this.privateKey = (ECPrivateKey)keyPair.getPrivate();
9599
this.curveName = curveName;
96100
}
97101

98102
public ECKeyPair(ECPublicKey publicKey, ECPrivateKey privateKey, String curveName) {
99-
this.keyPair = new KeyPair(publicKey, privateKey);
103+
this.privateKey = privateKey;
104+
this.publicKey = publicKey;
100105
this.curveName = curveName;
101106
}
102107

103108
public ECPublicKey getPublicKey() {
104-
return (ECPublicKey) this.keyPair.getPublic();
109+
return this.publicKey;
105110
}
106111

107112
public ECPrivateKey getPrivateKey() {
108-
return (ECPrivateKey) this.keyPair.getPrivate();
113+
return this.privateKey;
109114
}
110115

111116
public static int getECKeySize(String curveName) {
@@ -126,7 +131,7 @@ public String publicKeyInPEMFormat() {
126131
PemWriter pemWriter = new PemWriter(writer);
127132

128133
try {
129-
pemWriter.writeObject(new PemObject("PUBLIC KEY", this.keyPair.getPublic().getEncoded()));
134+
pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKey.getEncoded()));
130135
pemWriter.flush();
131136
pemWriter.close();
132137
} catch (IOException e) {
@@ -141,7 +146,7 @@ public String privateKeyInPEMFormat() {
141146
PemWriter pemWriter = new PemWriter(writer);
142147

143148
try {
144-
pemWriter.writeObject(new PemObject("PRIVATE KEY", this.keyPair.getPrivate().getEncoded()));
149+
pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKey.getEncoded()));
145150
pemWriter.flush();
146151
pemWriter.close();
147152
} catch (IOException e) {
@@ -152,70 +157,55 @@ public String privateKeyInPEMFormat() {
152157
}
153158

154159
public int keySize() {
155-
return this.keyPair.getPrivate().getEncoded().length * 8;
160+
return privateKey.getEncoded().length * 8;
156161
}
157162

158163
public String curveName() {
159164
return this.curveName;
160165
}
161166

162167
public byte[] compressECPublickey() {
163-
return ((ECPublicKey) this.keyPair.getPublic()).getQ().getEncoded(true);
168+
return getCompressedECPublicKey(publicKey);
164169
}
165170

166-
public static String getPEMPublicKeyFromX509Cert(String pemInX509Format) {
167-
try {
168-
PEMParser parser = new PEMParser(new StringReader(pemInX509Format));
169-
X509CertificateHolder x509CertificateHolder = (X509CertificateHolder) parser.readObject();
170-
parser.close();
171-
SubjectPublicKeyInfo publicKeyInfo = x509CertificateHolder.getSubjectPublicKeyInfo();
172-
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BOUNCY_CASTLE_PROVIDER);
173-
ECPublicKey publicKey = null;
174-
try {
175-
publicKey = (ECPublicKey) converter.getPublicKey(publicKeyInfo);
176-
} catch (PEMException e) {
177-
throw new RuntimeException(e);
178-
}
171+
private static byte[] getCompressedECPublicKey(PublicKey publicKey) {
172+
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(publicKey.getEncoded());
173+
X962Parameters params = X962Parameters.getInstance(publicKeyInfo.getAlgorithm().getParameters());
174+
if (params.isImplicitlyCA()) {
175+
throw new IllegalArgumentException("Implicitly CA parameters are not supported.");
176+
}
179177

180-
// EC public key to pem formated.
181-
StringWriter writer = new StringWriter();
182-
PemWriter pemWriter = new PemWriter(writer);
178+
ECCurve curve = ECNamedCurveTable.getByOID((ASN1ObjectIdentifier)params.getParameters()).getCurve();
179+
ECPoint p = curve.decodePoint(publicKeyInfo.getPublicKeyData().getOctets());
183180

184-
pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKey.getEncoded()));
185-
pemWriter.flush();
186-
pemWriter.close();
187-
return writer.toString();
188-
} catch (IOException e) {
189-
throw new RuntimeException(e);
190-
}
181+
return new X9ECPoint(p, true).getPointEncoding();
191182
}
192183

193184
public static byte[] compressECPublickey(String pemECPubKey) {
194185
try {
195-
KeyFactory ecKeyFac = KeyFactory.getInstance("EC", "BC");
186+
KeyFactory ecKeyFac = KeyFactory.getInstance("EC");
196187
PemReader pemReader = new PemReader(new StringReader(pemECPubKey));
197188
PemObject pemObject = pemReader.readPemObject();
198189
PublicKey pubKey = ecKeyFac.generatePublic(new X509EncodedKeySpec(pemObject.getContent()));
199-
return ((ECPublicKey) pubKey).getQ().getEncoded(true);
200-
} catch (NoSuchAlgorithmException e) {
201-
throw new RuntimeException(e);
202-
} catch (IOException e) {
203-
throw new RuntimeException(e);
204-
} catch (InvalidKeySpecException e) {
205-
throw new RuntimeException(e);
206-
} catch (NoSuchProviderException e) {
190+
return getCompressedECPublicKey(pubKey);
191+
} catch (NoSuchAlgorithmException | IOException | InvalidKeySpecException e) {
207192
throw new RuntimeException(e);
208193
}
209194
}
210195

211196
public static String publicKeyFromECPoint(byte[] ecPoint, String curveName) {
212197
try {
198+
ECPoint point = ECNamedCurveTable.getByName(curveName).getCurve().decodePoint(ecPoint);
199+
java.security.spec.ECPoint jpoint = new java.security.spec.ECPoint(point.getAffineXCoord().toBigInteger(), point.getAffineYCoord().toBigInteger());
200+
213201
// Create EC Public key
214-
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(curveName);
215-
ECPoint point = ecSpec.getCurve().decodePoint(ecPoint);
216-
ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(point, ecSpec);
217-
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
218-
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
202+
AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance("EC");
203+
algorithmParameters.init(new ECGenParameterSpec(curveName));
204+
ECParameterSpec ecParameterSpec = algorithmParameters.getParameterSpec(ECParameterSpec.class);
205+
206+
ECPublicKeySpec spec = new ECPublicKeySpec(jpoint, ecParameterSpec);
207+
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA");
208+
PublicKey publicKey = keyFactory.generatePublic(spec);
219209

220210
// EC Public keu to pem format.
221211
StringWriter writer = new StringWriter();
@@ -224,13 +214,7 @@ public static String publicKeyFromECPoint(byte[] ecPoint, String curveName) {
224214
pemWriter.flush();
225215
pemWriter.close();
226216
return writer.toString();
227-
} catch (InvalidKeySpecException e) {
228-
throw new RuntimeException(e);
229-
} catch (NoSuchAlgorithmException e) {
230-
throw new RuntimeException(e);
231-
} catch (NoSuchProviderException e) {
232-
throw new RuntimeException(e);
233-
} catch (IOException e) {
217+
} catch (InvalidKeySpecException | NoSuchAlgorithmException | IOException | InvalidParameterSpecException e) {
234218
throw new RuntimeException(e);
235219
}
236220
}
@@ -241,7 +225,7 @@ public static ECPublicKey publicKeyFromPem(String pemEncoding) {
241225
SubjectPublicKeyInfo publicKeyInfo = (SubjectPublicKeyInfo) parser.readObject();
242226
parser.close();
243227

244-
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BOUNCY_CASTLE_PROVIDER);
228+
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
245229
return (ECPublicKey) converter.getPublicKey(publicKeyInfo);
246230
} catch (IOException e) {
247231
throw new RuntimeException(e);
@@ -254,8 +238,7 @@ public static ECPrivateKey privateKeyFromPem(String pemEncoding) {
254238
PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) parser.readObject();
255239
parser.close();
256240

257-
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BOUNCY_CASTLE_PROVIDER);
258-
;
241+
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
259242
return (ECPrivateKey) converter.getPrivateKey(privateKeyInfo);
260243
} catch (IOException e) {
261244
throw new RuntimeException(e);
@@ -264,11 +247,11 @@ public static ECPrivateKey privateKeyFromPem(String pemEncoding) {
264247

265248
public static byte[] computeECDHKey(ECPublicKey publicKey, ECPrivateKey privateKey) {
266249
try {
267-
KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH", "BC");
250+
KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH");
268251
aKeyAgree.init(privateKey);
269252
aKeyAgree.doPhase(publicKey, true);
270253
return aKeyAgree.generateSecret();
271-
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException e) {
254+
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
272255
throw new RuntimeException(e);
273256
}
274257
}
@@ -285,34 +268,22 @@ public static byte[] calculateHKDF(byte[] salt, byte[] secret) {
285268

286269
public static byte[] computeECDSASig(byte[] digest, ECPrivateKey privateKey) {
287270
try {
288-
Signature ecdsaSign = Signature.getInstance("SHA256withECDSA", "BC");
271+
Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");
289272
ecdsaSign.initSign(privateKey);
290273
ecdsaSign.update(digest);
291274
return ecdsaSign.sign();
292-
} catch (NoSuchAlgorithmException e) {
293-
throw new RuntimeException(e);
294-
} catch (NoSuchProviderException e) {
295-
throw new RuntimeException(e);
296-
} catch (InvalidKeyException e) {
297-
throw new RuntimeException(e);
298-
} catch (SignatureException e) {
275+
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
299276
throw new RuntimeException(e);
300277
}
301278
}
302279

303280
public static Boolean verifyECDSAig(byte[] digest, byte[] signature, ECPublicKey publicKey) {
304281
try {
305-
Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA", "BC");
282+
Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA");
306283
ecdsaVerify.initVerify(publicKey);
307284
ecdsaVerify.update(digest);
308285
return ecdsaVerify.verify(signature);
309-
} catch (NoSuchAlgorithmException e) {
310-
throw new RuntimeException(e);
311-
} catch (NoSuchProviderException e) {
312-
throw new RuntimeException(e);
313-
} catch (InvalidKeyException e) {
314-
throw new RuntimeException(e);
315-
} catch (SignatureException e) {
286+
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
316287
throw new RuntimeException(e);
317288
}
318289
}

sdk/src/main/java/io/opentdf/platform/sdk/NanoTDF.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
import java.nio.ByteOrder;
1212
import java.nio.charset.StandardCharsets;
1313
import java.security.*;
14+
import java.security.interfaces.ECPublicKey;
1415
import java.util.*;
1516

1617
import com.google.gson.Gson;
1718
import com.google.gson.GsonBuilder;
1819

19-
import org.bouncycastle.jce.interfaces.ECPublicKey;
2020
import org.slf4j.Logger;
2121
import org.slf4j.LoggerFactory;
2222

sdk/src/main/java/io/opentdf/platform/sdk/TDF.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
import org.apache.commons.codec.DecoderException;
1616
import org.apache.commons.codec.binary.Hex;
17-
import org.bouncycastle.jce.interfaces.ECPublicKey;
1817
import org.slf4j.Logger;
1918
import org.slf4j.LoggerFactory;
2019

@@ -26,6 +25,7 @@
2625
import java.nio.channels.SeekableByteChannel;
2726
import java.nio.charset.StandardCharsets;
2827
import java.security.*;
28+
import java.security.interfaces.ECPublicKey;
2929
import java.text.ParseException;
3030
import java.util.*;
3131

0 commit comments

Comments
 (0)