此代码生成一对公钥/私钥的:

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

在第二个选项是更容易实现,但我不知道这是否可能是少高性能的。

任何建议?

有帮助吗?

解决方案

在我们的应用中,我们存储公钥和私钥DER格式,使他们能够使用,更容易操作之外的Java。在我们的例子中,私钥没有口令他们。

要私钥更容易使用的转换的东西在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;
}

很多人储存,然后密钥库。对于我们而言,我们需要将几种不同的语言在多个应用程序共享同一个密钥,并没有要复制磁盘上的文件。

在这两种情况下,性能不应该是一个巨大的问题,因为你很可能这些密钥存储在某种辛格尔顿或高速缓存,而不是每次都重新生成它们。

其他提示

您实际上是存储在两种情况下字节你是否意识到这一点。我认为正确的答案是在@布赖恩M.卡尔回答,这是存储在更高级别的对象在其最自然的形式暗示。在公开密钥的情况下,明显的选择是作为一个PKCS#1 RSAPublicKey ASN.1结构,DER编码,或作为X509 SubjectPublicKeyInfo进行ASN.1结构,DER编码。后者正是太阳提供给你,其中太阳级X509EncodedKeySpec支持。同样的,支持的PKCS8EncodedKeySpec私有密钥格式。这两种格式的标准,并通过OpenSSL的例如支持。孙趋向 - 往往:( - 支持现有的标准,而不是自己定义

如果要定义的格式,用于存储密钥,那么我会选择一种格式是消耗,这样,当你想改变加密(当旧的变弱为例)它不会破坏。

因此,我将存储字节编码为base64,与描述格式的字符串,“RSA”也许在一起。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top