Reputation: 14949
How to generate xml based RSA keys ( private ,public ) which should be compatible for .NET environment. I tried phpseclib module in PHP. But it is not compatible for .NET. Please suggest me any way to generate the xml based RSA keys in Java ? Actually I am working on linux based system. Using these keys I am going to perform encryption and decryption operation. Like
<RSAKeyValue>
<Modulus>4hjg1ibWXHIlH...ssmlBfMAListzrgk=</Modulus>
<Exponent>AQAB</Exponent>
<P>8QZCtrmJcr9uW7VRex+diH...jLHV5StmuBs1+vZZAQ==</P>
<Q>8CUvJTv...yeDszMWNCQ==</Q>
<DP>elh2Nv...cygE3657AQ==</DP>
<DQ>MBUh5XC...+PfiMfX0EQ==</DQ>
<InverseQ>oxvsj4WCbQ....LyjggXg==</InverseQ>
<D>KrhmqzAVasx...uxQ5VGZmZ6yOAE=</D>
</RSAKeyValue>
Upvotes: 4
Views: 12044
Reputation: 23
If someone wants do reverse operation - take RSAPrivateCrtKey by xml file, do not forget create instance of BigInteger with positive signum parameter.
new BigInteger(1, Base64.getDecoder().decode(encodedBigInteger));
It avoids of potential exception
java.security.SignatureException: Could not sign data
at sun.security.rsa.RSASignature.engineSign(RSASignature.java:178)
at java.security.Signature$Delegate.engineSign(Signature.java:1207)
at java.security.Signature.sign(Signature.java:579)
... more
Caused by: javax.crypto.BadPaddingException: Message is larger than modulus
at sun.security.rsa.RSACore.parseMsg(RSACore.java:214)
at sun.security.rsa.RSACore.crtCrypt(RSACore.java:166)
at sun.security.rsa.RSACore.rsa(RSACore.java:122)
at sun.security.rsa.RSASignature.engineSign(RSASignature.java:175)
... 6 more
Upvotes: 0
Reputation: 14225
There's no support for this out of the box in Java, but it's still fairly trivial. First off, you generate an RSA key pair using the JCA KeyPairGenerator
.
Then, you need to cast the private key to the appropriate interface (we use RSAPrivateCrtKey
instead of RSAPrivateKey
so we can access the CRT parts), and using Apache Commons Codec for Base64 encoding.
public static void main(String[] args) throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGen.genKeyPair();
RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) keyPair.getPrivate();
BigInteger n = privKey.getModulus();
BigInteger e = privKey.getPublicExponent();
BigInteger d = privKey.getPrivateExponent();
BigInteger p = privKey.getPrimeP();
BigInteger q = privKey.getPrimeQ();
BigInteger dp = privKey.getPrimeExponentP();
BigInteger dq = privKey.getPrimeExponentQ();
BigInteger inverseQ = privKey.getCrtCoefficient();
StringBuilder builder = new StringBuilder();
builder.append("<RSAKeyValue>\n");
write(builder, "Modulus", n);
write(builder, "Exponent", e);
write(builder, "P", p);
write(builder, "Q", q);
write(builder, "DP", dp);
write(builder, "DQ", dq);
write(builder, "InverseQ", inverseQ);
write(builder, "D", d);
builder.append("</RSAKeyValue>");
System.out.println(builder.toString());
}
private static void write(StringBuilder builder, String tag, BigInteger bigInt) {
builder.append("\t<");
builder.append(tag);
builder.append(">");
builder.append(encode(bigInt));
builder.append("</");
builder.append(tag);
builder.append(">\n");
}
private static String encode(BigInteger bigInt) {
return new String(Base64.encodeInteger(bigInt), "ASCII");
}
You can use a proper XML API if you're so inclined, but I felt no compelling reason not to use StringBuilder
in this case. Also, feel free to inline the BigInteger
instances. I declared them as variables to make the mapping between Java methods and XML elements more obvious.
Upvotes: 7