1. 检索 certificate 属性
使用 MOB(托管对象浏览器)检索证书信息,在浏览器地址栏输入下面的地址(其搜索路径为 ServiceInstance-> content -> ha-folder-root -> ha-datacenter -> ha-folder-host -> ha-compute-res -> ha-host -> config):
https://192.168.1.xxx/mob/?moid=ha-host&doPath=config
该地址进入的是 ESXi 主机配置信息对象 HostConfigInfo 的界面,里面有个 certificate 属性,如下图:
如上图,该 certificate 是一个十进制的字节数组,需要将该数组转为以十六进制展示的那种形式。
2. 根据主机名称获取 certificate 属性值
/**
* @Title: getCertificate
* @Description: 获取主机证书
* @param hostName
* @return
* @throws RuntimeFaultFaultMsg
* @throws InvalidPropertyFaultMsg
*/
@Override
public ArrayOfByte getCertificate(String hostName)
throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg {
// certificate属性
String[] propsArr = new String[] {"config.certificate"};
ManagedObjectReference hostMor = getMorByObjectName("HostSystem", hostName);
// 获取属性对应的实体
Map<String, Object> result = retrieveEntityProps(hostMor, propsArr);
ArrayOfByte certificate = null;
// 遍历结果
for (String key : result.keySet()) {
if ("config.certificate".equals(key)) {
certificate = (ArrayOfByte) result.get(key);
}
}
return certificate;
}
该方法获取到的 certificate 是十进制数组,结果如下:
45
45
45
45
45
66
69
71
73
78
32
67
.
.
.
3. 将十进制数组 certificate 转为十六进制
其中的证书字节数组转换只用到 byte2HexStr() 这个方法,其他互转方法当作一个记录供学习。
import java.net.URL;
import java.util.List;
import com.vmware.vim25.ArrayOfByte;
import cn.vms.VmClientSession;
import cn.vms.VmClientSessionFactory;
import cn.vms.entity.EsxiConnectionEntity;
/**
* @ClassName: HexUtil
* @Description: 10进制byte数组与16进制byte数组互转
*/
public class HexUtil {
/** 16进制中的字符集 */
private static final String HEX_CHAR = "0123456789ABCDEF";
/** 16进制中的字符集对应的字节数组 */
private static final byte[] HEX_STRING_BYTE = HEX_CHAR.getBytes();
/**
* 10进制字节数组转换为16进制字节数组
*
* byte用二进制表示占用8位,16进制的每个字符需要用4位二进制位来表示,则可以把每个byte
* 转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16进制字符,再取对应16进制字符的字节
*
* @param b 10进制字节数组
* @return 16进制字节数组
*/
public static byte[] byte2hex(byte[] b) {
int length = b.length;
byte[] b2 = new byte[length << 1];
int pos;
for (int i = 0; i < length; i++) {
pos = 2 * i;
b2[pos] = HEX_STRING_BYTE[(b[i] & 0xf0) >> 4];
b2[pos + 1] = HEX_STRING_BYTE[b[i] & 0x0f];
}
return b2;
}
/**
* 16进制字节数组转换为10进制字节数组
*
* 两个16进制字节对应一个10进制字节,则将第一个16进制字节对应成16进制字符表中的位置(0~15)并向左移动4位,
* 再与第二个16进制字节对应成16进制字符表中的位置(0~15)进行或运算,则得到对应的10进制字节
* @param b 10进制字节数组
* @return 16进制字节数组
*/
public static byte[] hex2byte(byte[] b) {
if (b.length % 2 != 0) {
throw new IllegalArgumentException("byte array length is not even!");
}
int length = b.length >> 1;
byte[] b2 = new byte[length];
int pos;
for (int i = 0; i < length; i++) {
pos = i << 1;
b2[i] = (byte) (HEX_CHAR.indexOf(b[pos]) << 4 | HEX_CHAR.indexOf(b[pos + 1]));
}
return b2;
}
/**
* 将16进制字节数组转成10进制字符串
*
* @param b 16进制字节数组
* @return 10进制字符串
*/
public static String hex2Str(byte[] b) {
return new String(hex2byte(b));
}
/**
* 将10进制字节数组转成16进制字符串
*
* @param b 10进制字节数组
* @return 16进制字符串
*/
public static String byte2HexStr(byte[] b) {
String hexStr = new String(b);
// int data = Integer.parseInt(sb);
// return Integer.toHexString(data);
return hexStr;
}
// 获取 Certificate 字节数组
public static ArrayOfByte getCertificateTest() throws Exception {
URL url = new URL("https://192.168.1.xxx/sdk/vimService?wsdl");
EsxiConnectionEntity esxiConnectionEntity = new EsxiConnectionEntity();
esxiConnectionEntity.setUrl(url);
esxiConnectionEntity.setUserName("root");
esxiConnectionEntity.setPassword("******");
VmClientSession vmClientSession = VmClientSessionFactory.bulidVmClientSession(esxiConnectionEntity, "userId");
ArrayOfByte certificate =
vmClientSession.getEsxiApi().getInventoryInfoApi().getCertificate("localhost.localdomain");
vmClientSession.close();
return certificate;
}
// 测试
public static void main(String[] args) throws Exception {
ArrayOfByte certificateByteArr = getCertificateTest();
List<Byte> certlist = certificateByteArr.getByte();
byte[] certb = new byte[certlist.size()];
for (int i = 0; i < certlist.size(); i++) {
// System.out.println(certlist.get(i));
certb[i] = certlist.get(i);
}
System.out.println(byte2HexStr(certb));
}
}
结果如下:
-----BEGIN CERTIFICATE-----
MIID8jCCAtqgAwIBAgIHAKlNwVk6VDANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQK
ExBWTXdhcmUgSW5zdGFsbGVyMB4XDTE3MDYwMjA3MDAxNFoXDTI4MTIwMTA3MDAx
NFowgfoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQH
EwlQYWxvIEFsdG8xFDASBgNVBAoTC1ZNd2FyZSwgSW5jMS4wLAYDVQQLEyVWTXdh
cmUgRVNYIFNlcnZlciBEZWZhdWx0IENlcnRpZmljYXRlMSowKAYJKoZIhvcNAQkB
Fhtzc2wtY2VydGlmaWNhdGVzQHZtd2FyZS5jb20xHjAcBgNVBAMTFWxvY2FsaG9z
dC5sb2NhbGRvbWFpbjEwMC4GCSqGSIb3DQEJAhMhMTQ5NjM4NjgxNCw1NjRkNzc2
MTcyNjUyMDQ5NmU2MzJlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
qyEZkKgZDfj04z3NLmQOuX4OAbbNHZYztU1Hp0C53fPS66cLVBvn0nKuk4PvNIZl
5dYcPBR+ifFrynM3z4dA7GXvHtCmSXnhdO7tyF8YxQkAHC4NcmKUcpwQ7B3lDtMf
eDO86IcX1nAMLjHXRDDppQOZAQg33SWne9uEbFPKTLZuvplhbE4JbBmRjdn39XfG
i2cL/QIN9XvxGmJluPI9DPlD3ijC83SgARRq8euL8ZSQiJRniy+iRnbxw6pMdR0K
ac+dqC13UBabVtFaveZdHY27w7foetG4weLqfx/9Qosl3re7cOKiLez/IQXHjo+i
qs/a63HXf5tSE4CevEE3IwIDAQABo1swWTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
sDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwIAYDVR0RBBkwF4IVbG9j
YWxob3N0LmxvY2FsZG9tYWluMA0GCSqGSIb3DQEBCwUAA4IBAQBlUL1d71h3S8DP
Tpz0FnfWlMd2dtuqnRtGvQz09nhCwQ2AUJv5mgcM34SuVM2HwyVl7MQwBc2s3dZg
gz+G6q5btKF9BQrheDxgfzKQrEO3mY11jh7+HREIR2usfoI5IPAoSBsmy/zbtkvr
2RZAjf/DTCW4uuIF0v0uU7V5Y5oFqetRH4yM3euPzWfaxEEeBxVV/UqiZyw306oo
n7C4JobuZH2Ht5kklunG9jMmigDLjAXoyXMP/eWRHc9p4pMUfypI8Pdz2l9mS+oC
W5ynFXXNKVVf2SkBj6Wf4+NPIe3OzL42YqCtK7YY+EW1GBZGAia6aYYa1hpTB/53
41zp9DyZ
-----END CERTIFICATE-----
然后可以通过命令行或其他工具根据该证书生成 ESXi 主机的 thumbprint。
参考:
Java 10进制byte数组与16进制byte数组互转 及 在DES加解密中的使用