我正在尝试使用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;
}
答案 0 :(得分:0)
好吧没关系,经过仔细检查看起来在我的情景中,幸运的是我可以单独使用HMAC:
private static bool Authenticate(string file, byte[] key, bool masterKey = false)
{
int position = 104;
if (masterKey) position = 48;
using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
using (var etm = new EtM_DecryptTransform(key, authenticateOnly: true))
{
fs.Position = position;
using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
cs.CopyTo(Stream.Null);
if (!etm.IsComplete) throw new Exception("Some blocks were not authenticated");
}
return true;
}
internal static void EncryptText(string text, Keyring k, string file, bool forSender)
{
SharedEphemeralBundle ephemeralBundle;
if (forSender) ephemeralBundle = k.SenderDHM.GetSharedEphemeralDhmSecret();
else ephemeralBundle = k.ReceiverDHM.GetSharedEphemeralDhmSecret();
var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob;
var ephemeralSymmetric = ephemeralBundle.SharedSecret;
var textBytes = text.ToBytes();
using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
{
fs.Write(ephemeralPublic, 0, ephemeralPublic.Length);
using (var etm = new EtM_EncryptTransform(ephemeralSymmetric))
using (var 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];
using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
fs.Read(ephemeralPublic, 0, 104);
var ephemeralSymmetric = k.SenderDHM.GetSharedDhmSecret(ephemeralPublic.ToPublicKeyFromBlob());
if (Authenticate(file, ephemeralSymmetric))
{
using (var etm = new EtM_DecryptTransform(ephemeralSymmetric))
using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
{
var decrypt = new byte[fs.Length - 104];
cs.Read(decrypt, 0, decrypt.Length);
decrypted = decrypt.FromBytes();
}
}
}
return decrypted;
}