如何使用 TPM2 签署消息?
How to sign message with TPM2?
来自 MethodA()
:
首先我创建了模板,然后是签名密钥。然后使用 ContextSave();
保存上下文并将其编组到文件。
来自 MethodB()
:
我解组了文件,并做了 ContextLoad();
这里它因完整性检查而失败。我做错了什么?
我这样创建了签名密钥:
var keyTemplate = new TpmPublic(TpmAlgId.Sha1, // Name algorithm
ObjectAttr.UserWithAuth | ObjectAttr.Sign | // Signing key
ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable
ObjectAttr.SensitiveDataOrigin,
null, // No policy
new RsaParms(new SymDefObject(),
new SchemeRsassa(TpmAlgId.Sha1), 2048, 0),
new Tpm2bPublicKeyRsa());
TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary(
TpmRh.Owner, // In the owner-hierarchy
new SensitiveCreate(keyAuth, null), // With this auth-value
keyTemplate, // Describes key
null, // Extra data for creation ticket
new PcrSelection[0], // Non-PCR-bound
out keyPublic, // PubKey and attributes
out creationData, out creationHash, out creationTicket); // Not used here
编辑 1:
方法A();
public static void MethodA()
{
try
{
Tpm2Device tpmDevice = new TcpTpmDevice(tpm_host, tpm_port);
//Tpm2Device tpmDevice = new TbsDevice();
tpmDevice.Connect();
var tpm = new Tpm2(tpmDevice);
if (tpmDevice is TcpTpmDevice)
{
tpmDevice.PowerCycle();
tpm.Startup(Su.Clear);
}
//
// The TPM needs a template that describes the parameters of the key
// or other object to be created. The template below instructs the TPM
// to create a new 2048-bit non-migratable signing key.
//
var keyTemplate = new TpmPublic(TpmAlgId.Sha1, // Name algorithm
ObjectAttr.UserWithAuth | ObjectAttr.Sign | // Signing key
ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable
ObjectAttr.SensitiveDataOrigin,
null, // No policy
new RsaParms(new SymDefObject(),
new SchemeRsassa(TpmAlgId.Sha1), 2048, 0),
new Tpm2bPublicKeyRsa());
//
// AuthValue encapsulates an authorization value: essentially a byte-array.
// OwnerAuth is the owner authorization value of the TPM-under-test. We
// assume that it (and other) auths are set to the default (null) value.
// If running on a real TPM, which has been provisioned by Windows, this
// value will be different. An administrator can retrieve the owner
// authorization value from the registry.
//
//var ownerAuth = new AuthValue();
//
// Authorization for the key we are about to create.
//
var keyAuth = new byte[] { 1, 2, 3 };
TpmPublic keyPublic;
CreationData creationData;
TkCreation creationTicket;
byte[] creationHash;
//
// Ask the TPM to create a new primary RSA signing key.
//
TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary(
TpmRh.Owner, // In the owner-hierarchy
new SensitiveCreate(keyAuth, null), // With this auth-value
keyTemplate, // Describes key
null, // Extra data for creation ticket
new PcrSelection[0], // Non-PCR-bound
out keyPublic, // PubKey and attributes
out creationData, out creationHash, out creationTicket); // Not used here
//
// Print out text-versions of the public key just created
//
//Console.WriteLine("New public key\n" + keyPublic.ToString());
Context ctx = tpm.ContextSave(keyHandle);
File.WriteAllBytes("key.bin", Marshaller.GetTpmRepresentation(ctx));
// Clean up.
tpm.FlushContext(keyHandle);
tpm.Dispose();
}
catch (Exception e)
{
Console.WriteLine("Exception occurred: {0}", e.Message);
}
}
方法B():
public static void MethodB()
{
try
{
Tpm2Device tpmDevice = new TcpTpmDevice(tpm_host, tpm_port);
//Tpm2Device tpmDevice = new TbsDevice();
tpmDevice.Connect();
var tpm = new Tpm2(tpmDevice);
if (tpmDevice is TcpTpmDevice)
{
tpmDevice.PowerCycle();
tpm.Startup(Su.Clear);
}
Context ctx2 = Marshaller.FromTpmRepresentation<Context>(File.ReadAllBytes("key.bin"));
TpmHandle keyHandle = tpm.ContextLoad(ctx2); //integrity check fail
此代码同时出现在 MethodA()
和 MethodB()
中:
if (tpmDevice is TcpTpmDevice)
{
tpmDevice.PowerCycle();
tpm.Startup(Su.Clear);
}
这是 TSS MSR 示例中的常见模式。它会检查您正在与之通话的 TPM 是否是模拟设备,如果是,则对其执行 Clear 命令,确保您从一个干净的平板开始。在 MethodA()
中这样做很好,但是在 MethodB()
中也这样做,你基本上是在撤销你在 MethodA()
中所做的事情:你刚刚创建的密钥被删除并且完整性检查因此失败了。
来自 MethodA()
:
首先我创建了模板,然后是签名密钥。然后使用 ContextSave();
保存上下文并将其编组到文件。
来自 MethodB()
:
我解组了文件,并做了 ContextLoad();
这里它因完整性检查而失败。我做错了什么?
我这样创建了签名密钥:
var keyTemplate = new TpmPublic(TpmAlgId.Sha1, // Name algorithm
ObjectAttr.UserWithAuth | ObjectAttr.Sign | // Signing key
ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable
ObjectAttr.SensitiveDataOrigin,
null, // No policy
new RsaParms(new SymDefObject(),
new SchemeRsassa(TpmAlgId.Sha1), 2048, 0),
new Tpm2bPublicKeyRsa());
TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary(
TpmRh.Owner, // In the owner-hierarchy
new SensitiveCreate(keyAuth, null), // With this auth-value
keyTemplate, // Describes key
null, // Extra data for creation ticket
new PcrSelection[0], // Non-PCR-bound
out keyPublic, // PubKey and attributes
out creationData, out creationHash, out creationTicket); // Not used here
编辑 1:
方法A();
public static void MethodA()
{
try
{
Tpm2Device tpmDevice = new TcpTpmDevice(tpm_host, tpm_port);
//Tpm2Device tpmDevice = new TbsDevice();
tpmDevice.Connect();
var tpm = new Tpm2(tpmDevice);
if (tpmDevice is TcpTpmDevice)
{
tpmDevice.PowerCycle();
tpm.Startup(Su.Clear);
}
//
// The TPM needs a template that describes the parameters of the key
// or other object to be created. The template below instructs the TPM
// to create a new 2048-bit non-migratable signing key.
//
var keyTemplate = new TpmPublic(TpmAlgId.Sha1, // Name algorithm
ObjectAttr.UserWithAuth | ObjectAttr.Sign | // Signing key
ObjectAttr.FixedParent | ObjectAttr.FixedTPM | // Non-migratable
ObjectAttr.SensitiveDataOrigin,
null, // No policy
new RsaParms(new SymDefObject(),
new SchemeRsassa(TpmAlgId.Sha1), 2048, 0),
new Tpm2bPublicKeyRsa());
//
// AuthValue encapsulates an authorization value: essentially a byte-array.
// OwnerAuth is the owner authorization value of the TPM-under-test. We
// assume that it (and other) auths are set to the default (null) value.
// If running on a real TPM, which has been provisioned by Windows, this
// value will be different. An administrator can retrieve the owner
// authorization value from the registry.
//
//var ownerAuth = new AuthValue();
//
// Authorization for the key we are about to create.
//
var keyAuth = new byte[] { 1, 2, 3 };
TpmPublic keyPublic;
CreationData creationData;
TkCreation creationTicket;
byte[] creationHash;
//
// Ask the TPM to create a new primary RSA signing key.
//
TpmHandle keyHandle = tpm[ownerAuth].CreatePrimary(
TpmRh.Owner, // In the owner-hierarchy
new SensitiveCreate(keyAuth, null), // With this auth-value
keyTemplate, // Describes key
null, // Extra data for creation ticket
new PcrSelection[0], // Non-PCR-bound
out keyPublic, // PubKey and attributes
out creationData, out creationHash, out creationTicket); // Not used here
//
// Print out text-versions of the public key just created
//
//Console.WriteLine("New public key\n" + keyPublic.ToString());
Context ctx = tpm.ContextSave(keyHandle);
File.WriteAllBytes("key.bin", Marshaller.GetTpmRepresentation(ctx));
// Clean up.
tpm.FlushContext(keyHandle);
tpm.Dispose();
}
catch (Exception e)
{
Console.WriteLine("Exception occurred: {0}", e.Message);
}
}
方法B():
public static void MethodB()
{
try
{
Tpm2Device tpmDevice = new TcpTpmDevice(tpm_host, tpm_port);
//Tpm2Device tpmDevice = new TbsDevice();
tpmDevice.Connect();
var tpm = new Tpm2(tpmDevice);
if (tpmDevice is TcpTpmDevice)
{
tpmDevice.PowerCycle();
tpm.Startup(Su.Clear);
}
Context ctx2 = Marshaller.FromTpmRepresentation<Context>(File.ReadAllBytes("key.bin"));
TpmHandle keyHandle = tpm.ContextLoad(ctx2); //integrity check fail
此代码同时出现在 MethodA()
和 MethodB()
中:
if (tpmDevice is TcpTpmDevice)
{
tpmDevice.PowerCycle();
tpm.Startup(Su.Clear);
}
这是 TSS MSR 示例中的常见模式。它会检查您正在与之通话的 TPM 是否是模拟设备,如果是,则对其执行 Clear 命令,确保您从一个干净的平板开始。在 MethodA()
中这样做很好,但是在 MethodB()
中也这样做,你基本上是在撤销你在 MethodA()
中所做的事情:你刚刚创建的密钥被删除并且完整性检查因此失败了。