I want to develop a Key generator for my phone applications. Currently I am using an external service to do the job but I am a little concerned that the service might go offline one day hence I will be in a bit of a pickle.
How authentication works now.
I like this and it works well, however, I want to create my own "Key Generation Service" from my own website.
Requirements:
Can someone give me some pointers on how to accomplish this? I have dabbled around with some java encryption but am definitely no expert and can't find anything that will help me.
A list of the Java classes I would need to instantiate would be helpful.
Interesting question which made me experiment a little bit with it. But as you might already have guessed, I haven't done this before. But maybe somebody else can confirm my thoughts - or rebut them but please without downvoting ;)
I'd use an asymmetric algorithm such as RSA to sign a string that consists of all the data that has to match in order to be valid. This signature is stored along with the public key in order to verify it without the need to access the server.
Expressed as Java code, this would look like this (based on Signature Sign and Verify):
import java.security.*;
public class Main {
public static void main(String args[]) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// our server, imagine it's a webservice
KeyServer server = new KeyServer(42);
// init client with a copy of public key from server
KeyClient client = new KeyClient(server.getPublicKey());
// create string that identifies phone and application
byte[] data = (getPhoneId() + ":" + getApplicationId()).getBytes("utf-8");
// send data to server for signature creation
byte[] digitalSignature = server.signData(data);
// verify on client side
System.out.println("verified = " + client.verifySig(data, digitalSignature));
// bad data
byte[] wrongData = ("anotherPhoneId" + ":" + getApplicationId()).getBytes("utf-8");
System.out.println("verified = " + client.verifySig(wrongData, digitalSignature));
// bad signature
digitalSignature[5] = (byte) 0xff;
System.out.println("verified = " + client.verifySig(data, digitalSignature));
}
private static String getPhoneId() {
return "somephone";
}
private static String getApplicationId() {
return "someapp";
}
public static class KeyClient {
private PublicKey _publicKey;
private Signature _signer;
public KeyClient(PublicKey publicKey) {
if (publicKey == null) {
throw new NullPointerException("publicKey");
}
_publicKey = publicKey;
try {
_signer = Signature.getInstance("SHA1withRSA");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("failed to get Signature", e);
}
}
public boolean verifySig(byte[] data, byte[] sig) throws Exception {
synchronized (_signer) {
_signer.initVerify(_publicKey);
_signer.update(data);
return (_signer.verify(sig));
}
}
}
public static class KeyServer {
private KeyPair _keyPair;
private Signature _signer;
public KeyServer(int seed) {
try {
_keyPair = generateKeyPair(seed);
} catch (Exception e) {
throw new RuntimeException("failed to generate key pair for seed " + seed, e);
}
try {
_signer = Signature.getInstance("SHA1withRSA");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("failed to get Signature", e);
}
}
public PublicKey getPublicKey() {
return _keyPair.getPublic();
}
public byte[] signData(byte[] data) throws InvalidKeyException, SignatureException {
synchronized (_signer) {
_signer.initSign(_keyPair.getPrivate());
_signer.update(data);
return (_signer.sign());
}
}
private KeyPair generateKeyPair(long seed) throws Exception {
KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom rng = SecureRandom.getInstance("SHA1PRNG", "SUN");
rng.setSeed(seed);
keyGenerator.initialize(2048, rng);
return (keyGenerator.generateKeyPair());
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With