序列化和反序列化RSA公钥

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

我在这里读到我不能将SecretKeySpec与RSA一起使用。

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

任何人都知道如何执行这些扭曲或这样做的方式。

来自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

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

所以,回顾一下:

 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。

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

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

我希望它有所帮助。