Domanda

Questo codice genera una coppia di chiavi pubblica/privata:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair keypair = keyGen.genKeyPair();
PrivateKey privateKey = keypair.getPrivate();
PublicKey publicKey = keypair.getPublic();

Quello che vorrei sapere è come si fa di solito memorizzare la chiave pubblica:

Opzione 1:memorizzare i byte

byte[] privateKeyBytes = privateKey.getEncoded();
byte[] publicKeyBytes = publicKey.getEncoded();
// ... write to file

// convert bytes back to public/private keys
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

Quello che non mi piace è quello di legare il codice di implementazioni concrete di come PKCS8EncodedKeySpec e X509EncodedKeySpec.

Opzione 2:memorizzare il modulo ed esponente

KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(publicKey, RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(privateKey,RSAPrivateKeySpec.class);

// store modulus and exponent as BigIntegers
BigInteger modulus = pub.getModulus());
BigInteger exponent = pub.getPublicExponent());
// ... write to file

// recreate public key (the same applies to the private key)
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);

La seconda opzione è più facile da implementare, ma non so se potrebbe essere meno performante.

Qualche consiglio ?

È stato utile?

Soluzione

Nelle nostre applicazioni, negozio di chiavi, pubblica e privata in formato DER modo che possano essere utilizzati e manipolati al di fuori di java più facilmente.Nel nostro caso, le chiavi private non hanno le password su di loro.

Per convertire la chiave privata di qualcosa di più facilmente utilizzabile in java:

openssl pkcs8 -topk8 -nocrypt -in key.pem -inform PEM -out key.der -outform DER

Quindi è possibile ottenere una chiave privata RSA direttamente da:

public static RSAPrivateKey getPrivateKey(File privateKeyFile) throws IOException, GeneralSecurityException {
    byte[] keyBytes = new byte[(int)privateKeyFile.length()];
    FileInputStream fis = new FileInputStream(privateKeyFile);
    fis.read(keyBytes);
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(spec);
    return privKey;
}

La chiave pubblica è simile:

openssl rsa -in private.pem -pubout -outform DER -out public.der

e leggete:

public static RSAPublicKey getPublicKey(File publicKeyFile) throws IOException, GeneralSecurityException {
    byte[] keyBytes = new byte[(int)publicKeyFile.length()];
    FileInputStream fis = new FileInputStream(publicKeyFile);
    fis.read(keyBytes);
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory factory = KeyFactory.getInstance("RSA");
    RSAPublicKey pubKey = (RSAPublicKey)factory.generatePublic(publicKeySpec);
    return pubKey;
}

Molte persone di archivio, quindi keystore.Per i nostri scopi, abbiamo bisogno della stessa chiave per essere condivisa tra più applicazioni in diverse lingue, e di non voler duplicare i file sul disco.

In entrambi i casi, le prestazioni non dovrebbe essere un problema enorme, perché è probabile che per memorizzare le chiavi in una sorta di Singleton o di cache invece di rigenerare ogni volta.

Altri suggerimenti

si sta effettivamente memorizzare i byte in entrambi i casi, se vi rendete conto o no. Suppongo che la risposta corretta è suggerita in @ Brian M. Carr risposta, che è quello di memorizzare l'oggetto di livello superiore nella sua forma più naturale. Nel caso di chiavi pubbliche, le scelte sono ovvie come RSAPublicKey ASN.1 struttura PKCS # 1, DER-codificati, o come struttura X509 SubjectPublicKeyInfo ASN.1, DER-encoded. Quest'ultimo è quello che i fornitori di Sole ti danno, cui la classe sole supporti X509EncodedKeySpec. Allo stesso modo, il PKCS8EncodedKeySpec supporta un formato di chiave privata. Entrambi questi formati sono standard, e sono supportati da openssl per esempio. Sun tende - la tendenza :( -. Per supportare gli standard esistenti piuttosto che definire il proprio

Se si desidera definire un formato per la memorizzazione delle chiavi, quindi vorrei scegliere un formato che è sacrificabile in modo che non si rompe quando si vuole la crittografia cambiamento (quando il vecchio si ottiene debole, per esempio).

Quindi mi sento di memorizzare i byte codificato come Base64, insieme con una stringa che descrive il formato, "rsa" forse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top