我正在尝试使用以下代码验证 tpm 报价的签名:
Signature publicSignature = Signature.getInstance("SHA1WithRSA");
publicSignature.initVerify(aik);
publicSignature.update(CryptoUtils.sha1(expectedBytes));
System.out.println(publicSignature.verify(quoteBytes));
但是我遇到了以下异常:
Exception in thread "main" java.security.SignatureException: Signature length not correct: got 256 but was expecting 281
看起来预期长度是根据密钥长度计算的,因为我使用的 AIK 公钥的长度是 281。所以现在的问题是为什么密钥长度是 281 而不是 256(对于 RSA 2048(?我必须以某种方式修剪十六进制字符串吗?
0000 0100 0100 0200 0000 0c00 0000 0008
0000 0200 0000 0000 0000 0001 4a95 8ebb
14da 7a5a 8d8f 0cf1 b918 9bda 9eda ec02
7e8a 9709 7a4c 05cf 396e e8cd 8e4d 0cb7
7151 ec15 186f 1856 9b3e 5c6d fde6 fd43
42d6 ebd6 a286 4150 b25b 03d8 1208 f434
c925 5045 07a0 3345 1cf9 1af8 b530 2191
81d8 e2a6 659d cdef c86c 1c25 1893 c26f
39a1 0222 69b8 2132 aadc 9b07 9906 ea73
a1c0 37af 0d81 b204 68cc 163e e95b bfca
d16e deed be06 a91d 2c9d 5bd0 5ccc c7ea
d142 aabb 2a6b 03dd 8cc2 4fca 9d0e 8dd6
09c0 c175 ec88 fd19 c6a1 e566 f9a9 391f
cf0e b493 e20c 7a91 6596 11ed 6fe7 7447
c197 e56b 961b 209a 1956 0b4b f330 28b9
c92f 998b 60bc 0919 fbd7 01e7 cca2 3a4b
5096 fb15 c877 78be 4560 f50d ae67 bddc
f5ad e514 2400 b89f 3c67 bfb1
我在这里偶然发现了答案。事实证明,AIK blob 中的前 28 个字节用于一个特殊的结构,该结构提供了有关算法、编码方案等的详细信息,其余 256 个字节表示模数。因此,在密钥上进行拼接是有效的:
byte[] modulusBytes = Arrays.copyOfRange(aikBytes, 28, aikBytes.length);
// Now get the public key object using:
RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(Hex.encodeHexString(modulusBytes), 16),
new BigInteger("010001", 16));
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey aik = factory.generatePublic(spec);