Merge pull request #263 from cubeee/move-rsa-keys

Move RSA keys to their own file and use a pem file for them
This commit is contained in:
Gary Tierney
2016-03-08 13:18:06 +00:00
6 changed files with 69 additions and 36 deletions
+1
View File
@@ -10,6 +10,7 @@
*.iml *.iml
/data/fs /data/fs
/data/rsa.pem
/data/savedGames /data/savedGames
/lib/ /lib/
*/target/ */target/
-5
View File
@@ -1,9 +1,4 @@
<net> <net>
<rsa>
<modulus>143690958001225849100503496893758066948984921380482659564113596152800934352119496873386875214251264258425208995167316497331786595942754290983849878549630226741961610780416197036711585670124061149988186026407785250364328460839202438651793652051153157765358767514800252431284681765433239888090564804146588087023</modulus>
<private-exponent>124425314960550024206991065332877157931472210939505789558012215720454903710618146200843877022273818555405810618059191162604008259757866640421952188957253368398733319663236323097864278319463888334484786055755767881706264786840339899269810859874287402892848784247637729987603089254067178011764721326471352835473</private-exponent>
</rsa>
<ports> <ports>
<http>80</http> <http>80</http>
<service>43594</service> <service>43594</service>
@@ -1,14 +1,21 @@
package org.apollo.net; package org.apollo.net;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.KeyFactory;
import org.apollo.util.xml.XmlNode; import java.security.Security;
import org.apollo.util.xml.XmlParser; import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import org.apollo.util.xml.XmlNode;
import org.apollo.util.xml.XmlParser;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
/** /**
* Holds various network-related constants such as port numbers. * Holds various network-related constants such as port numbers.
@@ -55,15 +62,6 @@ public final class NetworkConstants {
throw new IOException("Root node name is not 'net'."); throw new IOException("Root node name is not 'net'.");
} }
XmlNode rsa = net.getChild("rsa");
Preconditions.checkState(rsa != null, "Root node must have a child named 'rsa'.");
XmlNode modulus = rsa.getChild("modulus"), exponent = rsa.getChild("private-exponent");
Preconditions.checkState(modulus != null && exponent != null, "Rsa node must have two children: 'modulus' and 'private-exponent'.");
RSA_MODULUS = new BigInteger(modulus.getValue());
RSA_EXPONENT = new BigInteger(exponent.getValue());
XmlNode ports = net.getChild("ports"); XmlNode ports = net.getChild("ports");
Preconditions.checkState(ports != null, "Root node must have a child named 'ports'."); Preconditions.checkState(ports != null, "Root node must have a child named 'ports'.");
@@ -76,6 +74,20 @@ public final class NetworkConstants {
} catch (Exception exception) { } catch (Exception exception) {
throw new ExceptionInInitializerError(new IOException("Error parsing net.xml.", exception)); throw new ExceptionInInitializerError(new IOException("Error parsing net.xml.", exception));
} }
try (PemReader pemReader = new PemReader(new FileReader("data/rsa.pem"))) {
PemObject pem = pemReader.readPemObject();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pem.getContent());
Security.addProvider(new BouncyCastleProvider());
KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
RSAPrivateKey privateKey = (RSAPrivateKey) factory.generatePrivate(keySpec);
RSA_MODULUS = privateKey.getModulus();
RSA_EXPONENT = privateKey.getPrivateExponent();
} catch (Exception exception) {
throw new ExceptionInInitializerError(new IOException("Error parsing rsa.pem", exception));
}
} }
/** /**
+7
View File
@@ -81,6 +81,12 @@
<version>0.9.5.2</version> <version>0.9.5.2</version>
</dependency> </dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.54</version>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
@@ -101,6 +107,7 @@
<version>1.6.4</version> <version>1.6.4</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>
+1
View File
@@ -22,4 +22,5 @@
<sourceDirectory>src/main</sourceDirectory> <sourceDirectory>src/main</sourceDirectory>
<testSourceDirectory>src/test</testSourceDirectory> <testSourceDirectory>src/test</testSourceDirectory>
</build> </build>
</project> </project>
@@ -1,45 +1,62 @@
package org.apollo.util.tools; package org.apollo.util.tools;
import java.math.BigInteger; import java.io.FileWriter;
import java.security.SecureRandom; import java.security.KeyPair;
import java.util.Random; import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
/** /**
* An RSA key generator. * An RSA key generator.
* *
* @author Graham * @author Graham
* @author Major * @author Major
* @author Cube
*/ */
public final class RsaKeyGenerator { public final class RsaKeyGenerator {
/** /**
* The bit count. <strong>Strongly</strong> recommended to be at least 2,048. * The bit count.
* <strong>Note:</strong> 2048 bits and above are not compatible with the client without modifications
*/ */
private static final int BIT_COUNT = 2_048; private static final int BIT_COUNT = 1024;
/**
* The path to the private key file.
*/
private static final String PRIVATE_KEY_FILE = "data/rsa.pem";
/** /**
* The entry point of the RsaKeyGenerator. * The entry point of the RsaKeyGenerator.
* *
* @param args The application arguments. * @param args The application arguments.
*/ */
public static void main(String[] args) { public static void main(String[] args) throws Exception {
Random random = new SecureRandom(); Security.addProvider(new BouncyCastleProvider());
BigInteger publicKey = BigInteger.valueOf(65_537); KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
BigInteger p, q, phi, modulus, privateKey; keyPairGenerator.initialize(BIT_COUNT);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
do { RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
p = BigInteger.probablePrime(BIT_COUNT / 2, random); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
q = BigInteger.probablePrime(BIT_COUNT / 2, random);
phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
modulus = p.multiply(q); System.out.println("Place these keys in the client:");
privateKey = publicKey.modInverse(phi); System.out.println("--------------------");
} while (modulus.bitLength() != BIT_COUNT || privateKey.bitLength() != BIT_COUNT || !phi.gcd(publicKey).equals(BigInteger.ONE)); System.out.println("public key: " + publicKey.getPublicExponent());
System.out.println("modulus: " + publicKey.getModulus());
System.out.println("modulus: " + modulus); try (PemWriter writer = new PemWriter(new FileWriter(PRIVATE_KEY_FILE))) {
System.out.println("public key: " + publicKey); writer.writeObject(new PemObject("RSA PRIVATE KEY", privateKey.getEncoded()));
System.out.println("private key: " + privateKey); } catch (Exception e) {
System.err.println("Failed to write private key to " + PRIVATE_KEY_FILE);
e.printStackTrace();
}
} }
} }