2010-05-24 4 views
5

Chcę opracować generator kluczy do moich aplikacji telefonicznych. Obecnie używam usługi zewnętrznej do wykonania tej pracy, ale jestem trochę zaniepokojony tym, że usługa może zostać odłączona pewnego dnia, więc będę w stanie odrobiny marności.Budowanie generatora klucza aktywacyjnego w JAVA

Sposób uwierzytelniania działa teraz.

  1. Klucz publiczny przechowywany w telefonie.
  2. Gdy użytkownik zażąda klucza, "identyfikator telefonu" jest wysyłany do "usługi generowania klucza", a zaszyfrowany klucz jest zwracany i przechowywany w pliku licencji.
  3. W telefonie mogę sprawdzić, czy klucz jest dla bieżącego telefonu za pomocą metody getPhoneId(), którą mogę sprawdzić w bieżącym telefonie i przyznać lub nie przyznać dostępu do funkcji.

Podoba mi się to i działa dobrze, jednak chcę stworzyć własną "usługę generowania klucza" z mojej własnej strony internetowej.

Wymagania:

  1. Public and Private Key
  2. Szyfrowanie: (nadmuchiwany zamek)
  3. napisany w Javie
  4. Musi obsługiwać getApplicationId() (tak, że wiele aplikacji może korzystać z tego samego key generator) i getPhoneId() (aby uzyskać identyfikator telefonu z zaszyfrowanego pliku licencji)
  5. Chcę móc wysłać ApplicationId i telefon Id do usługi generowania kluczy licencyjnych.

Czy ktoś może mi podać wskazówki, jak to osiągnąć? Poufnąłem się z jakimś szyfrowaniem java, ale zdecydowanie nie jestem ekspertem i nie mogę znaleźć niczego, co mogłoby mi pomóc.

Pomocna byłaby lista klas Java, których potrzebowałbym do utworzenia wystąpienia.

+0

@jax - czy udało Ci się znaleźć odpowiedź na to pytanie? Również szukam bezpiecznego klucza aktywacyjnego. – Stevko

+0

Tak, teraz go poleruję - mogę powiedzieć, że to duży problem w # $% $. – jax

+1

Informacje na ten temat są skąpe i kiedy zadajesz pytanie, ludzie mówią ci, że jeśli nie rozumiesz, nie powinieneś tego robić - co moim zdaniem jest śmieszne - jak ludzie się uczą! Kiedy skończę mój API, mogę go sprzedać z doridprofessor.com. Jednakże, jeśli chcesz, abyś był właścicielem, spójrz na andappstore.com, mają na usługi online, które robi to za Ciebie. Możesz spojrzeć na ich kod i trochę go poprawić. Wspólna klasa Base64 jest również bardzo przydatna do zakodowania licencji binarnych w formie czytelnej dla tekstu. – jax

Odpowiedz

1

Interesujące pytanie, które pozwoliło mi trochę z nim eksperymentować. Ale jak już się domyśliliście, nie robiłem tego wcześniej. Ale może ktoś może potwierdzić moje myśli - albo je obalić, ale proszę bez downvoting;)

bym użyć asymmetric algorithm takich jak RSA podpisać ciąg znaków, który zawiera wszystkie dane, które musi pasować, aby być ważne . Podpis ten jest przechowywany razem z kluczem publicznym w celu jego weryfikacji bez konieczności uzyskiwania dostępu do serwera.

Wyrażone jako kodu Java, będzie to wyglądać następująco (na podstawie 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

Kolumnę, że chociaż istnieją algorytmy, które są na tyle silne, że problem jest w jaki sposób z nich korzystać problem ponieważ jeśli połączysz te algorytmy w niewłaściwy sposób lub użyjesz złych nasion dla niektórych algorytmów, słabe klucze (np. ich długość), otrzymasz coś, co nie jest bezpieczne. Więc doświadczenie mówi, że lepiej jest nie próbować implementować tego samodzielnie i ryzykować błędy, dopóki nie będziesz wystarczająco pewny z teorią kryptologii.

Jednak druga odpowiedź wydaje się dawać dobry przykład.

Powiązane problemy