序列化和反序列化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());
我希望它有所帮助。