Pages

Monday, 8 May 2017

Get RSA PublicKey from XML Key Format

Here is a script (prototype) in Groovy to get RSA PublicKey from XML public key. You might encounter such XML keys, say during .NET interop.
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory
import org.w3c.dom.Document
import java.nio.charset.StandardCharsets
import java.security.spec.RSAPublicKeySpec
import java.security.KeyFactory
import java.security.PublicKey

def rsaPubXML = "ANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9VAQAB"
def docBuilderFactory = DocumentBuilderFactory.newInstance()
def docBuilder = docBuilderFactory.newDocumentBuilder()

def b64Decode(enc) {
    Base64.getDecoder().decode(enc)
}

Document xmlDoc = docBuilder.parse(new ByteArrayInputStream(rsaPubXML.getBytes(StandardCharsets.UTF_8)))

def modulus = xmlDoc.getElementsByTagName("Modulus").item(0).textContent
def exponent = xmlDoc.getElementsByTagName("Exponent").item(0).textContent
println "modulus: ${modulus}\nexponent: ${exponent}"

RSAPublicKeySpec keySpec = new RSAPublicKeySpec(new BigInteger(b64Decode(modulus)), new BigInteger(b64Decode(exponent)));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(keySpec);

println "key: ${key}"
This gives the following output.
modulus: ANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9V
exponent: AQAB
key: Sun RSA public key, 1024 bits
  modulus: 154774478177095248394968828543369801032226937226535865231262824893513573019304152154974259955740337204606655133945162319470662684517274530901497375379716962851415879364453962123395223899051919634994929603613704222239797911292193776910691509004328773391280872757318122152217457361921195935350223751896771182421
  public exponent: 65537
Note that the modulus must be a positive integer. If you are working with other JVM languages and are getting a negative integer value, specify the signum as 1 in the BigInteger(1, b64Decode(modulus)) function call. The exponent must always be 65537 as of now because that is the largest Fermat's Prime known today.

No comments:

Post a Comment