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:
zzz
2016-01-21 21:38:26 +00:00
parent f29ed21090
commit 9cdd0fc829
3 changed files with 57 additions and 16 deletions

View File

@ -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);
}
****/
}

View File

@ -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 ||

View File

@ -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 ||