2010-05-24 13 views
5

Desidero sviluppare un generatore di chiavi per le mie applicazioni telefoniche. Attualmente sto usando un servizio esterno per fare il lavoro, ma sono un po 'preoccupato che il servizio potrebbe andare offline un giorno, quindi sarò un po' sottaceto.Creazione di un generatore di "Chiave di attivazione" in JAVA

Come funziona ora l'autenticazione.

  1. Chiave pubblica memorizzata nel telefono.
  2. Quando l'utente richiede una chiave, l''ID telefono' viene inviato al "Servizio di generazione chiavi" e la chiave crittografata viene restituita e memorizzata all'interno di un file di licenza.
  3. Sul telefono posso verificare se la chiave è per il telefono corrente utilizzando un metodo getPhoneId() che posso verificare con il telefono corrente e concedere o non concedere l'accesso alle funzionalità.

Mi piace e funziona bene, tuttavia, voglio creare il mio "servizio di generazione delle chiavi" dal mio sito web.

Requisiti:

  1. chiavi pubblica e privata
  2. Encryption: (Bouncy Castle)
  3. scritto in Java
  4. Deve supportare getApplicationId() (in modo che molte applicazioni possono utilizzare lo stesso generatore di chiavi) e getPhoneId() (per estrarre l'ID del telefono dal file di licenza crittografato)
  5. Desidero poter inviare ApplicationId e Phone Id al servizio per la generazione della chiave di licenza.

Qualcuno può darmi alcune indicazioni su come realizzare questo? Mi sono dilettato con un po 'di crittografia java ma non sono assolutamente esperto e non riesco a trovare nulla che possa aiutarmi.

Un elenco delle classi Java che avrei bisogno di creare un'istanza sarebbe utile.

+0

@jax - hai avuto qualche successo nella ricerca di questa domanda? Anch'io sto cercando un generatore di chiavi di attivazione sicuro. – Stevko

+0

sì, lo sto lucidando in questo momento - posso dirti che è un grande problema il # $% $ da fare. – jax

+1

Le informazioni su questo argomento sono scarse e quando fai una domanda le persone ti dicono che se non capisci non dovresti farlo - il che penso sia del tutto ridicolo - come le persone imparano! Una volta finita la mia API potrei venderla da doridprofessor.com. Tuttavia, se vuoi farti tuo, dare un'occhiata a andappstore.com, hanno un servizio online che fa questo per te. Puoi guardare il loro codice e decodificarlo un po '. La classe Base64 comune è anche molto utile per codificare le licenze binarie in forma leggibile dal testo. – jax

risposta

1

Interessante domanda che mi ha fatto sperimentare un po '. Ma come avrete già intuito, non l'ho mai fatto prima. Ma forse qualcun altro può confermare i miei pensieri - o rebut loro ma per favore senza downvoting;)

Io userei uno asymmetric algorithm come RSA per firmare una stringa che consiste di tutti i dati che devono corrispondere per essere validi . Questa firma viene archiviata insieme alla chiave pubblica per verificarla senza la necessità di accedere al server.

Espressa in codice Java, questo sarebbe simile a questa (sulla base di 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()); 
    } 

    } 
} 
1

Il problema è che anche se ci sono algoritmi che sono abbastanza forti, il problema è come si fa a usarli, perché se si combinano questi algoritmi in modo errato o si utilizzano semi non validi per alcuni algoritmi, i tasti deboli (ad esempio la loro lunghezza) si ritroveranno con qualcosa che non è sicuro. Quindi l'esperienza dice, è meglio, non provare a implementarla da soli e rischiare errori finché non si è abbastanza sicuri della teoria della crittologia.

Tuttavia, l'altra risposta sembra dare un buon esempio.

Problemi correlati