I am given a 120 char ECDSA generated X509 public key by an external system. I now want to use it in Ethereum by converting it to an address.
(not the real key but an example of the content (120 chars))
MFYwEAYHKoZIzj0CAQYFK4EE123456789n9DSxZh3wfq0BIL5LDF5B54e07bxFiKc89K/GaKj4qrGC/Mb/KnakQBrN4khMQHLnxm7TjaxXQPxtJMV5b+A==
I can't see an easy way of doing this with web3j, perhaps there is another way?
I think, looking at the tests, org.web3j.crypto.Keys.getAddress(String)
expects the 130 character hex version.
How do I convert the 120 chars to a 130 char hex representation to allow me to call the getAddress method or maybe there is a direct way of converting the 120 char pub key to Ethereum address?
If you had a valid Base64 encoded SECP-256k1 public key, the following code would enable you to get the Ethereum address using Web3j.
String encodedKey = "MFYwEAYHKoZIzj0CAQYFK4EE123456789n9DSxZh3wfq0BIL5LDF5B54e07bxFiKc89K/GaKj4qrGC/Mb/KnakQBrN4khMQHLnxm7TjaxXQPxtJMV5b+A==";
byte[] decoded = Base64.getDecoder().decode(encodedKey);
String address = Keys.getAddress(Numeric.toHexString(decoded));
However, as mentioned in the comments, it appears that the input encoded key is not a 128 bit public key, but an X.509 cert. Hence you'll need to do something along these lines:
String encodedKey = "MFYwEAYHKoZIzj0CAQYFK4EE123456789n9DSxZh3wfq0BIL5LDF5B54e07bxFiKc89K/GaKj4qrGC/Mb/KnakQBrN4khMQHLnxm7TjaxXQPxtJMV5b+A==";
byte[] decoded = Base64.getDecoder().decode(encodedKey);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(decoded));
// TODO: Figure out how to convert this PublicKey into a byte array or BigInteger
byte[] publicKey = cert.getPublicKey();
String address = Keys.getAddress(Hex.toHexString(publicKey));
It's also worth mentioning that the OpenSSL command line tool can be very helpful too for converting certificates into different formats.