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
/data/fs
/data/rsa.pem
/data/savedGames
/lib/
*/target/
-5
View File
@@ -1,9 +1,4 @@
<net>
<rsa>
<modulus>143690958001225849100503496893758066948984921380482659564113596152800934352119496873386875214251264258425208995167316497331786595942754290983849878549630226741961610780416197036711585670124061149988186026407785250364328460839202438651793652051153157765358767514800252431284681765433239888090564804146588087023</modulus>
<private-exponent>124425314960550024206991065332877157931472210939505789558012215720454903710618146200843877022273818555405810618059191162604008259757866640421952188957253368398733319663236323097864278319463888334484786055755767881706264786840339899269810859874287402892848784247637729987603089254067178011764721326471352835473</private-exponent>
</rsa>
<ports>
<http>80</http>
<service>43594</service>
@@ -1,14 +1,21 @@
package org.apollo.net;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import org.apollo.util.xml.XmlNode;
import org.apollo.util.xml.XmlParser;
import java.security.KeyFactory;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
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.
@@ -55,15 +62,6 @@ public final class NetworkConstants {
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");
Preconditions.checkState(ports != null, "Root node must have a child named 'ports'.");
@@ -76,6 +74,20 @@ public final class NetworkConstants {
} catch (Exception 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>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.54</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@@ -101,6 +107,7 @@
<version>1.6.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
+1
View File
@@ -22,4 +22,5 @@
<sourceDirectory>src/main</sourceDirectory>
<testSourceDirectory>src/test</testSourceDirectory>
</build>
</project>
@@ -1,45 +1,62 @@
package org.apollo.util.tools;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;
import java.io.FileWriter;
import java.security.KeyPair;
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.
*
* @author Graham
* @author Major
* @author Cube
*/
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.
*
* @param args The application arguments.
*/
public static void main(String[] args) {
Random random = new SecureRandom();
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
BigInteger publicKey = BigInteger.valueOf(65_537);
BigInteger p, q, phi, modulus, privateKey;
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
keyPairGenerator.initialize(BIT_COUNT);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
do {
p = BigInteger.probablePrime(BIT_COUNT / 2, random);
q = BigInteger.probablePrime(BIT_COUNT / 2, random);
phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
modulus = p.multiply(q);
privateKey = publicKey.modInverse(phi);
} while (modulus.bitLength() != BIT_COUNT || privateKey.bitLength() != BIT_COUNT || !phi.gcd(publicKey).equals(BigInteger.ONE));
System.out.println("Place these keys in the client:");
System.out.println("--------------------");
System.out.println("public key: " + publicKey.getPublicExponent());
System.out.println("modulus: " + publicKey.getModulus());
System.out.println("modulus: " + modulus);
System.out.println("public key: " + publicKey);
System.out.println("private key: " + privateKey);
try (PemWriter writer = new PemWriter(new FileWriter(PRIVATE_KEY_FILE))) {
writer.writeObject(new PemObject("RSA PRIVATE KEY", privateKey.getEncoded()));
} catch (Exception e) {
System.err.println("Failed to write private key to " + PRIVATE_KEY_FILE);
e.printStackTrace();
}
}
}