序列化和反序列化RSA公钥

时间:2014-02-06 15:03:26

标签: java

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();

我想从byte[]创建公钥。

我尝试过这个实验:

publicKey = new SecretKeySpec(publicKey.getEncoded(), publicKey.getAlgorithm());

但是使用该密钥进行解密会失败。

我也尝试使用ObjectOutputStream序列化密钥,但序列化失败。

  

java.io.NotSerializableException:org.apache.harmony.xnet.provider.jsse.OpenSSLKey

我读了here我无法将SecretKeySpec与RSA一起使用。

  

因此,只要您谈论的是SecretKey而不是RSA或DSA密钥,那么您就不必经历涉及KeyGenerator等的任何扭曲。

任何人都知道如何进行这些扭曲或这样做。

3 个答案:

答案 0 :(得分:6)

取决于您想要对序列化表示做什么。如果消费者不是您自己的程序,请随意滚动您自己的实现。公共RSA密钥由两个整数组成 - 指数和模数。模数很大 - 大约1024位,指数通常为17位。如果将公钥对象强制转换为BigInteger,则两者都可用作RSAPublicKey个对象。

所以,回顾一下:

RSAPublicKey publicKey = (RSAPublicKey)kp.getPublic();
return publicKey.getModulus().toString() + "|" +
    publicKey.getPublicExponent().toString();

这足以恢复密钥。要反序列化:

String []Parts = MyKeyString.split("\\|");
RSAPublicKeySpec Spec = new RSAPublicKeySpec(
        new BigInteger(Parts[0]),
        new BigInteger(Parts[1]));
return KeyFactory.getInstance("RSA").generatePublic(Spec);

如果需要将密钥传递给第三方软件,最好将其序列化为标准格式 - PEM或DER。

答案 1 :(得分:5)

来自RSA的非对称密钥通常以X509格式存储。因此,您可以使用X509EncodedKeySpec代替。

一个简单的例子已经在Java 7 JavaDoc中了(只需用RSA替换DSA): http://docs.oracle.com/javase/7/docs/api/java/security/KeyFactory.html

X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);

如果您需要从byte[]反序列化私有,我发现您必须使用PKCS8EncodedKeySpec

答案 2 :(得分:1)

我使用以下代码将PubliKey转换为PEM Base64格式

String publicKeyString = javax.xml.bind.DatatypeConverter.printBase64Binary(publicKey.getEncoded());

我希望它有所帮助。