我正在尝试使用EC Diffie-Hellman和两个不同的提供程序来加密/解密消息: Microsoft软件密钥存储提供程序和 Microsoft平台加密提供程序。 以下代码适用于前者,而无法正确解密:
bool usePlatform = true; // works correctly when false
CngProvider provider = usePlatform
? new CngProvider("Microsoft Platform Crypto Provider")
: CngProvider.MicrosoftSoftwareKeyStorageProvider;
const string message = "Hello, world!";
byte[] encryptedMessage;
// create keys
CngKey providerKey1 = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256, "test key 1", new CngKeyCreationParameters()
{
Provider = provider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
ExportPolicy = CngExportPolicies.None,
});
byte[] publicKey1 = providerKey1.Export(CngKeyBlobFormat.EccPublicBlob);
CngKey providerKey2 = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256, "test key 2", new CngKeyCreationParameters()
{
Provider = provider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
ExportPolicy = CngExportPolicies.None,
});
byte[] publicKey2 = providerKey2.Export(CngKeyBlobFormat.EccPublicBlob);
// encrypt with the private key 1 and the public key 2
using (SymmetricAlgorithm symmetricKey = new AesCng()
{
Padding = PaddingMode.Zeros,
Key = new ECDiffieHellmanCng(providerKey1) { KeySize = 256 }
.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(publicKey2, CngKeyBlobFormat.EccPublicBlob))
})
{
symmetricKey.GenerateIV();
using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor())
using (MemoryStream dataStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(dataStream, encryptor, CryptoStreamMode.Write))
{
dataStream.Write(symmetricKey.IV, 0, symmetricKey.IV.Length);
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
cryptoStream.Write(messageBytes, 0, messageBytes.Length);
}
symmetricKey.Clear();
encryptedMessage = dataStream.ToArray();
}
}
string decryptedMessage;
// decrypt with the private key 2 and the public key 1
using (SymmetricAlgorithm symmetricKey = new AesCng()
{
Padding = PaddingMode.Zeros,
Key = new ECDiffieHellmanCng(providerKey2) { KeySize = 256 }
.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(publicKey1, CngKeyBlobFormat.EccPublicBlob))
})
{
symmetricKey.IV = encryptedMessage.Take(symmetricKey.BlockSize >> 3).ToArray();
using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor())
using (MemoryStream dataStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(dataStream, decryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(encryptedMessage, symmetricKey.IV.Length, encryptedMessage.Length - symmetricKey.IV.Length);
}
symmetricKey.Clear();
decryptedMessage = Encoding.UTF8.GetString(dataStream.ToArray()).Trim('\0');
}
}
Debug.Assert(message == decryptedMessage); // the decrypted message doesn't match the original one
解密对称密钥将加密对称密钥与软件提供程序匹配,并且在使用平台提供程序时有所不同。我究竟做错了什么?这是TPM的某些使用问题吗?