forked from I2P_Developers/i2p.i2p
Crypto: Fix privkey encoding to follow PKCS8,
ignore example in josefsson draft, required for keytool to work. Fix pubkey decode typo. (ticket #1723)
This commit is contained in:
@ -479,6 +479,7 @@ public class KeyStoreUtil {
|
||||
List<String> a = new ArrayList<String>(32);
|
||||
a.add(keytool);
|
||||
a.add("-genkey"); // -genkeypair preferred in newer keytools, but this works with more
|
||||
//a.add("-v"); // verbose, gives you a stack trace on exception
|
||||
a.add("-storetype"); a.add(KeyStore.getDefaultType());
|
||||
a.add("-keystore"); a.add(ks.getAbsolutePath());
|
||||
a.add("-storepass"); a.add(ksPW);
|
||||
@ -765,6 +766,7 @@ public class KeyStoreUtil {
|
||||
* KeyStoreUtil import file.ks file.key alias keypw (imxports private key from file to keystore)
|
||||
* KeyStoreUtil export file.ks alias keypw (exports private key from keystore)
|
||||
* KeyStoreUtil keygen file.ks alias keypw (create keypair in keystore)
|
||||
* KeyStoreUtil keygen2 file.ks alias keypw (create keypair using I2PProvider)
|
||||
*/
|
||||
/****
|
||||
public static void main(String[] args) {
|
||||
@ -781,6 +783,10 @@ public class KeyStoreUtil {
|
||||
testKeygen(args);
|
||||
return;
|
||||
}
|
||||
if (args.length > 0 && "keygen2".equals(args[0])) {
|
||||
testKeygen2(args);
|
||||
return;
|
||||
}
|
||||
File ksf = (args.length > 0) ? new File(args[0]) : null;
|
||||
if (ksf != null && !ksf.exists()) {
|
||||
createKeyStore(ksf, DEFAULT_KEYSTORE_PASSWORD);
|
||||
@ -835,5 +841,26 @@ public class KeyStoreUtil {
|
||||
DEFAULT_KEY_VALID_DAYS, "EdDSA", 256, pw);
|
||||
System.out.println("genkey ok? " + ok);
|
||||
}
|
||||
|
||||
private static void testKeygen2(String[] args) throws Exception {
|
||||
// keygen test using the I2PProvider
|
||||
SigType type = SigType.EdDSA_SHA512_Ed25519;
|
||||
java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName());
|
||||
kpg.initialize(type.getParams());
|
||||
java.security.KeyPair kp = kpg.generateKeyPair();
|
||||
java.security.PublicKey jpub = kp.getPublic();
|
||||
java.security.PrivateKey jpriv = kp.getPrivate();
|
||||
|
||||
System.out.println("Encoded private key:");
|
||||
System.out.println(net.i2p.util.HexDump.dump(jpriv.getEncoded()));
|
||||
System.out.println("Encoded public key:");
|
||||
System.out.println(net.i2p.util.HexDump.dump(jpub.getEncoded()));
|
||||
|
||||
java.security.Signature jsig = java.security.Signature.getInstance("SHA512withEdDSA");
|
||||
jsig.initSign(jpriv);
|
||||
jsig.update(new byte[111]);
|
||||
net.i2p.data.Signature sig = SigUtil.fromJavaSig(jsig.sign(), type);
|
||||
System.out.println("Signature test: " + sig);
|
||||
}
|
||||
****/
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
|
||||
/**
|
||||
* This follows the spec at
|
||||
* https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04
|
||||
* NOT the docs from
|
||||
* AND the docs from
|
||||
* java.security.spec.PKCS8EncodedKeySpec
|
||||
* quote:
|
||||
*<pre>
|
||||
@ -77,39 +77,43 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
|
||||
* }
|
||||
*</pre>
|
||||
*
|
||||
* @return 39 bytes for Ed25519, null for other curves
|
||||
* Note that the private key encoding is not fully specified in the Josefsson draft,
|
||||
* and the example is wrong, as it's lacking Version and AlgorithmIdentifier.
|
||||
* But sun.security.pkcs.PKCS8Key expects them so we must include them for keytool to work.
|
||||
*
|
||||
* @return 49 bytes for Ed25519, null for other curves
|
||||
* @since implemented in 0.9.25
|
||||
*/
|
||||
public byte[] getEncoded() {
|
||||
// TODO no equals() implemented in spec, but it's essentially a singleton
|
||||
if (!edDsaSpec.equals(EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)))
|
||||
return null;
|
||||
int totlen = 7 + seed.length;
|
||||
int totlen = 17 + seed.length;
|
||||
byte[] rv = new byte[totlen];
|
||||
int idx = 0;
|
||||
// sequence
|
||||
rv[idx++] = 0x30;
|
||||
rv[idx++] = (byte) (5 + seed.length);
|
||||
rv[idx++] = (byte) (15 + seed.length);
|
||||
|
||||
// version
|
||||
// not in the Josefsson example
|
||||
//rv[idx++] = 0x02;
|
||||
//rv[idx++] = 1;
|
||||
//rv[idx++] = 0;
|
||||
rv[idx++] = 0x02;
|
||||
rv[idx++] = 1;
|
||||
rv[idx++] = 0;
|
||||
|
||||
// Algorithm Identifier
|
||||
// sequence
|
||||
// not in the Josefsson example
|
||||
//rv[idx++] = 0x30;
|
||||
//rv[idx++] = (byte) (10 + seed.length);
|
||||
rv[idx++] = 0x30;
|
||||
rv[idx++] = 8;
|
||||
// OID 1.3.101.100
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb540809%28v=vs.85%29.aspx
|
||||
// not in the Josefsson example
|
||||
//rv[idx++] = 0x06;
|
||||
//rv[idx++] = 3;
|
||||
//rv[idx++] = (1 * 40) + 3;
|
||||
//rv[idx++] = 101;
|
||||
//rv[idx++] = 100;
|
||||
rv[idx++] = 0x06;
|
||||
rv[idx++] = 3;
|
||||
rv[idx++] = (1 * 40) + 3;
|
||||
rv[idx++] = 101;
|
||||
rv[idx++] = 100;
|
||||
// params
|
||||
rv[idx++] = 0x0a;
|
||||
rv[idx++] = 1;
|
||||
@ -132,7 +136,17 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
|
||||
try {
|
||||
int idx = 0;
|
||||
if (d[idx++] != 0x30 ||
|
||||
d[idx++] != 37 ||
|
||||
d[idx++] != 47 ||
|
||||
d[idx++] != 0x02 ||
|
||||
d[idx++] != 1 ||
|
||||
d[idx++] != 0 ||
|
||||
d[idx++] != 0x30 ||
|
||||
d[idx++] != 8 ||
|
||||
d[idx++] != 0x06 ||
|
||||
d[idx++] != 3 ||
|
||||
d[idx++] != (1 * 40) + 3 ||
|
||||
d[idx++] != 101 ||
|
||||
d[idx++] != 100 ||
|
||||
d[idx++] != 0x0a ||
|
||||
d[idx++] != 1 ||
|
||||
d[idx++] != 1 ||
|
||||
|
@ -118,7 +118,7 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
|
||||
d[idx++] != 0x30 ||
|
||||
d[idx++] != 8 ||
|
||||
d[idx++] != 0x06 ||
|
||||
d[idx++] != 1 ||
|
||||
d[idx++] != 3 ||
|
||||
d[idx++] != (1 * 40) + 3 ||
|
||||
d[idx++] != 101 ||
|
||||
d[idx++] != 100 ||
|
||||
|
Reference in New Issue
Block a user