使用 SHA1 从多个值计算聚合
Using SHA1 to calculate an aggregate from multiple values
我正在使用完整性测量架构 (IMA) (https://sourceforge.net/p/linux-ima/wiki/Home/) 并且我正在尝试在 Java 中写入他们已经在 C 中完成并在上面的链接页面中解释的内容.
从测量列表开始:
PCR-00: 07274edf7147abda49200100fd668ce2c3a374d7
PCR-01:48dff4fbf3a34d56a08dfc1504a3a9d707678ff7
PCR-02:53de584dcef03f6a7dac1a240a835893896f218d
PCR-03:3a3f780f11a4b49969fcaa80cd6e3957c33b2275
PCR-04:acb44e9dd4594d3f121df2848f572e4d891f0574
PCR-05:df72e880e68a2b52e6b6738bb4244b932e0f1c76
PCR-06:585e579e48997fee8efd20830c6a841eb353c628
PCR-07:3a3f780f11a4b49969fcaa80cd6e3957c33b2275
我需要计算所有这些测量值的总和。执行此操作的 C 代码是:
SHA1_Init(&c);
for (i = 0; i < NUM_PCRS; i++) {
if (DEBUG) {
printf("PCR-%2.2x: ", i);
display_sha1_digest(pcr[i].digest);
}
SHA1_Update(&c, pcr[i].digest, 20);
}
SHA1_Final(boot_aggregate, &c);
使用这段代码的结果是:b5a166c10d153b7cc3e5b4f1eab1f71672b7c524
我写了 java 行来做到这一点:
String pcr0 = "07274edf7147abda49200100fd668ce2c3a374d7";
String pcr1 = "48dff4fbf3a34d56a08dfc1504a3a9d707678ff7";
String pcr2 = "53de584dcef03f6a7dac1a240a835893896f218d";
String pcr3 = "3a3f780f11a4b49969fcaa80cd6e3957c33b2275";
String pcr4 = "acb44e9dd4594d3f121df2848f572e4d891f0574";
String pcr5 = "df72e880e68a2b52e6b6738bb4244b932e0f1c76";
String pcr6 = "585e579e48997fee8efd20830c6a841eb353c628";
String pcr7 = "3a3f780f11a4b49969fcaa80cd6e3957c33b2275";
MessageDigest hash = MessageDigest.getInstance("SHA-1");
byte[] firstToLastDigest;
hash.reset();
hash.update(pcr0.getBytes("UTF-8"));;
hash.update(pcr1.getBytes("UTF-8"));
hash.update(pcr2.getBytes("UTF-8"));
hash.update(pcr3.getBytes("UTF-8"));
hash.update(pcr4.getBytes("UTF-8"));
hash.update(pcr5.getBytes("UTF-8"));
hash.update(pcr6.getBytes("UTF-8"));
hash.update(pcr7.getBytes("UTF-8"));
firstToLastDigest = hash.digest();
digestStr = javax.xml.bind.DatatypeConverter.printHexBinary(firstToLastDigest);
System.out.println(digestStr);
但我得到的是 "EA3487AC70DC445A2E608ED44DC550366F2C6716" 而不是预期结果:"b5a166c10d153b7cc3e5b4f1eab1f71672b7c524"。有什么建议吗?
注意您的 C 程序中的大小:
SHA1_Update(&c, pcr[i].digest, 20);
这告诉您 pcr[i].digest
是一个 20 字节的数组。它只是为了显示而转换为十六进制格式,但在内部,它只有 20 个字节。
现在您所做的是获取摘要的十六进制表示形式(长度为 40 个字符)并将其放入摘要中。这意味着,如果您的 PCR 摘要是 07274edf7...
,您将获取字符 0
的值、字符 7
的值,依此类推,然后对其进行消化。
这是不正确的。您应该消化 0x07
、0x27
等值
因此,如果您拥有的只是值的十六进制表示形式,则应首先将其解析为字节数组。不使用 String.getBytes("UTF-8")
- 这只会为您提供字符串中字符的字节值!您可能可以使用 javax.xml.bind.DatatypeConverter.parseHexBinary
.
但在真正的程序中,而不是将 PCR 设置为字符串的程序中,您应该已经拥有 20 字节长的数组,它们是先前摘要的结果(使用 printHexBinary
之前的值) .这就是您应该用来更新摘要的值。
我正在使用完整性测量架构 (IMA) (https://sourceforge.net/p/linux-ima/wiki/Home/) 并且我正在尝试在 Java 中写入他们已经在 C 中完成并在上面的链接页面中解释的内容.
从测量列表开始:
PCR-00: 07274edf7147abda49200100fd668ce2c3a374d7
PCR-01:48dff4fbf3a34d56a08dfc1504a3a9d707678ff7
PCR-02:53de584dcef03f6a7dac1a240a835893896f218d
PCR-03:3a3f780f11a4b49969fcaa80cd6e3957c33b2275
PCR-04:acb44e9dd4594d3f121df2848f572e4d891f0574
PCR-05:df72e880e68a2b52e6b6738bb4244b932e0f1c76
PCR-06:585e579e48997fee8efd20830c6a841eb353c628
PCR-07:3a3f780f11a4b49969fcaa80cd6e3957c33b2275
我需要计算所有这些测量值的总和。执行此操作的 C 代码是:
SHA1_Init(&c);
for (i = 0; i < NUM_PCRS; i++) {
if (DEBUG) {
printf("PCR-%2.2x: ", i);
display_sha1_digest(pcr[i].digest);
}
SHA1_Update(&c, pcr[i].digest, 20);
}
SHA1_Final(boot_aggregate, &c);
使用这段代码的结果是:b5a166c10d153b7cc3e5b4f1eab1f71672b7c524
我写了 java 行来做到这一点:
String pcr0 = "07274edf7147abda49200100fd668ce2c3a374d7";
String pcr1 = "48dff4fbf3a34d56a08dfc1504a3a9d707678ff7";
String pcr2 = "53de584dcef03f6a7dac1a240a835893896f218d";
String pcr3 = "3a3f780f11a4b49969fcaa80cd6e3957c33b2275";
String pcr4 = "acb44e9dd4594d3f121df2848f572e4d891f0574";
String pcr5 = "df72e880e68a2b52e6b6738bb4244b932e0f1c76";
String pcr6 = "585e579e48997fee8efd20830c6a841eb353c628";
String pcr7 = "3a3f780f11a4b49969fcaa80cd6e3957c33b2275";
MessageDigest hash = MessageDigest.getInstance("SHA-1");
byte[] firstToLastDigest;
hash.reset();
hash.update(pcr0.getBytes("UTF-8"));;
hash.update(pcr1.getBytes("UTF-8"));
hash.update(pcr2.getBytes("UTF-8"));
hash.update(pcr3.getBytes("UTF-8"));
hash.update(pcr4.getBytes("UTF-8"));
hash.update(pcr5.getBytes("UTF-8"));
hash.update(pcr6.getBytes("UTF-8"));
hash.update(pcr7.getBytes("UTF-8"));
firstToLastDigest = hash.digest();
digestStr = javax.xml.bind.DatatypeConverter.printHexBinary(firstToLastDigest);
System.out.println(digestStr);
但我得到的是 "EA3487AC70DC445A2E608ED44DC550366F2C6716" 而不是预期结果:"b5a166c10d153b7cc3e5b4f1eab1f71672b7c524"。有什么建议吗?
注意您的 C 程序中的大小:
SHA1_Update(&c, pcr[i].digest, 20);
这告诉您 pcr[i].digest
是一个 20 字节的数组。它只是为了显示而转换为十六进制格式,但在内部,它只有 20 个字节。
现在您所做的是获取摘要的十六进制表示形式(长度为 40 个字符)并将其放入摘要中。这意味着,如果您的 PCR 摘要是 07274edf7...
,您将获取字符 0
的值、字符 7
的值,依此类推,然后对其进行消化。
这是不正确的。您应该消化 0x07
、0x27
等值
因此,如果您拥有的只是值的十六进制表示形式,则应首先将其解析为字节数组。不使用 String.getBytes("UTF-8")
- 这只会为您提供字符串中字符的字节值!您可能可以使用 javax.xml.bind.DatatypeConverter.parseHexBinary
.
但在真正的程序中,而不是将 PCR 设置为字符串的程序中,您应该已经拥有 20 字节长的数组,它们是先前摘要的结果(使用 printHexBinary
之前的值) .这就是您应该用来更新摘要的值。