0

外部系统为我提供了一个 120 字符的 ECDSA 生成的 X509 公钥。我现在想通过将其转换为地址来在以太坊中使用它。

(不是真正的密钥,而是内容示例(120 个字符)) MFYwEAYHKoZIzj0CAQYFK4EE123456789n9DSxZh3wfq0BIL5LDF5B54e07bxFiKc89K/GaKj4qrGC/Mb/KnakQBrN4khMQHLnxm7TjaxXQPxtJMV5b+A==

我看不到使用 web3j 执行此操作的简单方法,也许还有另一种方法?我认为,看看测试,org.web3j.crypto.Keys.getAddress(String)预计会有 130 个字符的十六进制版本。

如何将120 个字符转换为130 个字符的十六进制表示,以允许我调用 getAddress 方法,或者是否有将 120 个字符的 pub 密钥转换为以太坊地址的直接方法?

4

1 回答 1

2

如果你有一个有效的 Base64 编码的 SECP-256k1 公钥,下面的代码将使你能够使用 Web3j 获取以太坊地址。

String encodedKey = "MFYwEAYHKoZIzj0CAQYFK4EE123456789n9DSxZh3wfq0BIL5LDF5B54e07bxFiKc89K/GaKj4qrGC/Mb/KnakQBrN4khMQHLnxm7TjaxXQPxtJMV5b+A==";
byte[] decoded = Base64.getDecoder().decode(encodedKey);
String address = Keys.getAddress(Numeric.toHexString(decoded));

但是,正如评论中提到的,输入的编码密钥似乎不是 128 位公钥,而是 X.509 证书。因此,您需要按照以下方式做一些事情:

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));

还值得一提的是,OpenSSL 命令行工具对于将证书转换为不同格式也非常有帮助。

于 2020-05-05T16:59:04.010 回答