我正在尝试使用 Inferno 对使用 ECIES 加密的文本文件进行签名。加密和密钥交换部分运行良好,但我还有一些关于 ECDSA 的问题。
1-我猜ECDSA签名必须存储在发送的文件中,以便接收者可以使用它来验证数据完整性,对吗?
2-我读过很多次应该对散列数据执行签名,但是使用 ECIES 发送的数据是加密的,而不是散列的,否则接收方如何检索它?
3- 在下面的代码示例中应该在哪里进行签名?当前尝试不起作用,因为尽管在解密时接受了签名,但会返回一个空字符串(而不是解密的文本)。
internal static void EncryptText(string text, Keyring k, string file, bool forSender)
{
// never mind the Keyring class, it has no methods and only exposes
// a few properties to store the session keys conveniently
SharedEphemeralBundle ephemeralBundle;
if (forSender) ephemeralBundle = k.SenderDHM.GetSharedEphemeralDhmSecret();
else ephemeralBundle = k.ReceiverDHM.GetSharedEphemeralDhmSecret();
var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob;
var ephemeralSymmetric = ephemeralBundle.SharedSecret;
var textBytes = Utils.SafeUTF8.GetBytes(text);
byte[] signature;
using (var ecdsa = new ECDsaCng(k.SenderDSA) { HashAlgorithm = CngAlgorithm.Sha384 })
signature = ecdsa.SignData(textBytes);
using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
{
fs.Write(signature, 0, signature.Length);
fs.Write(ephemeralPublic, 0, ephemeralPublic.Length);
EtM_EncryptTransform etm = new EtM_EncryptTransform(ephemeralSymmetric);
using (CryptoStream cs = new CryptoStream(fs, etm, CryptoStreamMode.Write))
cs.Write(textBytes, 0, textBytes.Length);
}
}
internal static string DecryptText(string file, Keyring k)
{
string decrypted = null;
var ephemeralPublic = new byte[104];
var signature = new byte[96];
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
fs.Read(signature, 0, 96);
fs.Read(ephemeralPublic, 0, 104);
var ephemeralSymmetric = k.SenderDHM.GetSharedDhmSecret(ephemeralPublic.ToPublicKeyFromBlob());
EtM_DecryptTransform etm = new EtM_DecryptTransform(ephemeralSymmetric);
using (CryptoStream cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
{
byte[] decrypt = new byte[fs.Length - 200];
cs.Read(decrypt, 0, decrypt.Length);
using (var ecdsa = new ECDsaCng(k.SenderDSA))
{
// signature is accepted but returns an empty string!?
if (ecdsa.VerifyData(decrypt, signature))
decrypted = Utils.SafeUTF8.GetString(decrypt);
}
}
}
return decrypted;
}