Question

Ce code génère une paire de clés public / privé:

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

Ce que je voudrais savoir est comment voulez-vous stocker généralement la clé publique:

Option 1: stocker les octets

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);

Ce que je ne aime pas est de lier le code à des réalisations concrètes telles que PKCS8EncodedKeySpec et X509EncodedKeySpec.

Option 2: stocker le module et l'exposant

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 deuxième option est plus facile à mettre en œuvre, mais je ne sais pas si cela pourrait être moins performant.

Tout conseil?

Était-ce utile?

La solution

Dans nos applications, nous stockons les clés publiques et privées au format DER afin qu'ils puissent être utilisés et manipulés plus facilement java à l'extérieur. Dans notre cas, les clés privées ne sont pas les mots de passe sur eux.

Pour convertir la clé privée à quelque chose plus facilement utilisable en java:

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

Ensuite, vous pouvez obtenir une clé privée RSA directement par:

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 clé publique est similaire:

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

et de le lire:

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;
}

Beaucoup de gens stockent keystores puis. Pour nos besoins, nous avions besoin de la même clé pour être partagée entre plusieurs applications en plusieurs langues différentes, et ne voulait pas dupliquer les fichiers sur le disque.

Dans les deux cas, la performance ne devrait pas être une préoccupation majeure, parce que vous êtes susceptible de stocker les clés dans une sorte de Singleton ou cache au lieu de les régénérer à chaque fois.

Autres conseils

Vous stockez effectivement les octets dans les deux cas que vous le réalisiez ou non. Je suppose que la bonne réponse est en réponse fait allusion à M. Carr @ Brian, qui est de stocker l'objet de niveau supérieur dans sa forme la plus naturelle. Dans le cas des clés publiques, les choix les plus évidents sont comme une structure ASN.1 RSAPublicKey PKCS # 1, DER-encoded, ou comme une structure ASN.1 X509 SubjectPublicKeyInfo, codé DER. Ce dernier est ce que les fournisseurs Sun vous donnent, ce qui la classe soleil supports X509EncodedKeySpec. De même, le PKCS8EncodedKeySpec prend en charge un format de clé privée. Ces deux formats sont standards et sont pris en charge par OpenSSL par exemple. Sun a tendance - tendance :( -. Pour soutenir les normes existantes plutôt que de définir leur propre

Si vous souhaitez définir un format de stockage des clés, alors je choisirais un format consomptibles pour qu'il ne se casse pas quand vous voulez le chiffrement de changement (lorsque l'ancien arrive à faible par exemple).

Je voudrais donc stocker les octets encodée en base64, avec une chaîne qui décrit le format, « rsa » peut-être.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top