質問

このコードは、公開/秘密鍵のペアを生成します:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair keypair = keyGen.genKeyPair();
PrivateKey privateKey = keypair.getPrivate();
PublicKey publicKey = keypair.getPublic();
私が知りたいのですが何が通常の公開鍵を格納しない方法です。

オプション1:ストア

バイト
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);
私は好きではないことは、このようなPKCS8EncodedKeySpecX509EncodedKeySpecなど、具体的な実装にコードを結びつけることです。

オプション2:係数を格納し、指数

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

二番目のオプションは、実装が簡単ですが、それはあまりパフォーマンスの可能性があれば、私は知りません。

任意のアドバイス?

役に立ちましたか?

解決

彼らは使用してより簡単に外のjavaを操作することができるように、

は、当社のアプリケーションでは、我々は、DER形式で公開鍵と秘密鍵を格納します。我々の場合には、秘密鍵は、それらのパスワードを持っていません。

Javaで何かに、より簡単に使用可能な秘密鍵を変換するには:

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

そして、あなたがして直接RSA秘密鍵を取得することができます:

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

は、公開鍵は似てます:

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

と、それを読むために:

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

多くの人が、その後キーストアを格納します。我々の目的のために、我々はいくつかの異なる言語で複数のアプリケーション間で共有するために同じキーを必要とし、ディスク上のファイルを複製したくありませんでした。

あなたがそれらを毎回再生成するのではなく、シングルトンやキャッシュのいくつかの並べ替えでは、これらのキーを格納するためにそうしているので、

はいずれの場合も、パフォーマンスは、大きな関心事ではありません。

他のヒント

あなたが実際にあなたがそれを実現するかどうか、両方のケースでバイトを保存しています。私は、正しい答えが最も自然な形で、より高いレベルのオブジェクトを格納することです@Brian M.カーの答えは、中で示唆されているとします。公開鍵の場合には、明白な選択肢であるPKCS#1のRSAPublicKeyのASN.1構造として、DER符号化され、又はX509 SubjectPublicKeyInfoでASN.1構造として、DER符号化されました。後者は、Sunのプロバイダは、太陽のクラスX509EncodedKeySpecの支援をあなたを与えるものです。同様に、あるPKCS8EncodedKeySpecは、秘密鍵のフォーマットをサポートしています。これらの両方のフォーマットは標準で、例えばopensslのサポートされています。 Sunは傾向がある - 傾向が見られた:( - 自分自身を定義ではなく、既存の規格をサポートするために、

あなたが鍵を格納するためのフォーマットを定義したい場合は、

、その後、私はあなたが(古いものは、例えば、弱になったとき)の暗号化を変更したいとき、それは壊れていないことを消耗そうであるフォーマットを選択することになります。

私は一緒に多分フォーマットを説明する文字列、「RSA」と、BASE64として符号化されたバイト格納しますので。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top