2012-03-27 10 views

Odpowiedz

14

można zrobić coś takiego:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
kpg.initialize(2048); 

KeyPair kp = kpg.genKeyPair(); 

KeyFactory fact = KeyFactory.getInstance("RSA"); 

RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), 
     RSAPublicKeySpec.class); 
saveToFile(PUBLIC_KEY_FILE, 
     pub.getModulus(), pub.getPublicExponent()); 

RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), 
     RSAPrivateKeySpec.class); 
saveToFile(PRIVATE_KEY_FILE, 
     priv.getModulus(), priv.getPrivateExponent()); 

SAVE Funkcja:

private static void saveToFile(String fileName, 
           BigInteger mod, BigInteger exp) 
    throws SomeException { 
    ObjectOutputStream oout = new ObjectOutputStream(
      new BufferedOutputStream(new FileOutputStream(fileName))); 
    try { 
     oout.writeObject(mod); 
     oout.writeObject(exp); 
    } catch (Exception e) { 
     throw new SomeException(e); 
    } finally { 
     oout.close(); 
    } 
} 

I czytać tę samą drogę powrotną :

private static PublicKey readPublicKey() throws SomeException { 
    InputStream in = new FileInputStream(PUBLIC_KEY_FILE); 
    ObjectInputStream oin = 
      new ObjectInputStream(new BufferedInputStream(in)); 
    try { 
     BigInteger m = (BigInteger) oin.readObject(); 
     BigInteger e = (BigInteger) oin.readObject(); 
     RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e); 
     KeyFactory fact = KeyFactory.getInstance("RSA"); 
     PublicKey pubKey = fact.generatePublic(keySpec); 
     return pubKey; 
    } catch (Exception e) { 
     throw new SomeException(e); 
    } finally { 
     oin.close(); 
    } 
} 

Czytanie klucza prywatnego jest podobne.

+2

@segfault, Należy także pamiętać, że trzeba '' dodać to w 'AndroidManifest.xml ' – Israel

+6

Czy bezpiecznie przechowywać klucz prywatny w pamięci dostępnej przez inne aplikacje? (Popraw mnie, jeśli się mylę, ale tak właśnie się stało.) – cph2117

+0

To ty musisz skonfigurować uprawnienia do pliku na poziomie systemu operacyjnego (np. Dedykowany użytkownik dla aplikacji itp.). Niewiarygodne, wykracza to poza zakres tej odpowiedzi. –

0

http://snipplr.com/view/18368/

lub

http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.html

lub

http://java.sun.com/docs/books/tutorial/security/apisign/vstep2.html Jest to najbardziej obiecujące

lub

Niemożliwe jest zabezpieczenie klucza w niezaufanym środowisku. Możesz zaciemnić swój kod, możesz utworzyć klucz z dowolnych zmiennych, cokolwiek. Ostatecznie, zakładając, że używasz standardowej biblioteki javax.crypto, musisz zadzwonić do Mac.getInstance(), a czasem później nazwiesz init() na tym wystąpieniu. Ktoś, kto chce twój klucz, dostanie to.

Jednak myślę, że rozwiązaniem jest powiązanie klucza z otoczeniem, a nie z programem. Podpis ma na celu stwierdzenie, że dane pochodzą ze znanego źródła i nie zostały zmienione, ponieważ to źródło je dostarczyło. Obecnie próbujesz powiedzieć "gwarancja, że ​​mój program wygenerował dane". Zamiast tego zmień swoje wymagania, aby "zagwarantować, że dany użytkownik mojego programu wygenerował dane". Zobowiązanie zostaje następnie przeniesione na tego użytkownika, aby zajął się swoim kluczem.

7

Ten blok kodu wygeneruje i zapisze KeyPair w AndroidKeyStore. (UWAGA: połowy wyjątków pominięta)

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keyStore.load(null); 

String alias = "my_key"; // replace as required or get it as a function argument 

int nBefore = keyStore.size(); // debugging variable to help convince yourself this works 

// Create the keys if necessary 
if (!keyStore.containsAlias(alias)) { 

    Calendar notBefore = Calendar.getInstance(); 
    Calendar notAfter = Calendar.getInstance(); 
    notAfter.add(Calendar.YEAR, 1); 
    KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(this) 
        .setAlias(alias) 
        .setKeyType("RSA") 
        .setKeySize(2048) 
        .setSubject(new X500Principal("CN=test")) 
        .setSerialNumber(BigInteger.ONE) 
        .setStartDate(notBefore.getTime()) 
        .setEndDate(notAfter.getTime()) 
        .build(); 
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); 
    generator.initialize(spec); 

    KeyPair keyPair = generator.generateKeyPair(); 
} 
int nAfter = keyStore.size(); 
Log.v(TAG, "Before = " + nBefore + " After = " + nAfter); 

// Retrieve the keys 
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null); 
RSAPrivateKey privateKey = (RSAPrivateKey) privateKeyEntry.getPrivateKey(); 
RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey(); 

Log.v(TAG, "private key = " + privateKey.toString()); 
Log.v(TAG, "public key = " + publicKey.toString()); 
+0

OK, to powinno działać tylko dla Androida. Co powiesz na Java? – Andy

+0

KeyPairGeneratorSpec jest przestarzałe. Zobacz: https://stackoverflow.com/questions/35269954/keypairgeneratorspec-deprecated – Gary89

Powiązane problemy