gpt4 book ai didi

c# - .NET 中的最小消息大小公钥加密

转载 作者:可可西里 更新时间:2023-11-01 08:44:39 26 4
gpt4 key购买 nike

我想使用公钥加密系统将非常少的数据(准确地说是 15 个字节)加密成尽可能短(最好不超过 16 个字节)的消息。

不幸的是,标准公钥系统 RSA 会生成与其 key 一样大的消息,即大约 100 字节,具体取决于 key 大小。更困难的是,我只能使用 .NET 框架库,即没有第三方。

我在维基百科上阅读了一些关于椭圆曲线密码学的内容,那里的文字似乎暗示那里的 key 长度通常比 RSA key 短得多。

这也可以转化为短消息吗? .NET ECDiffieHellmanCng 类是否可用于解密/加密消息?它似乎具有与 RSA 或对称密码不同的类结构。

最佳答案

您可以使用 ECDiffieHellman 来加密消息。您有两种选择:静态-静态 ECDH 和静态-短暂 ECDH:

对于静态-静态 ECDH,接收方需要知道发送方的公钥(这在您的应用程序中可能是也可能不是)。您还应该有一些对于此消息是唯一的数据(它可能是您从协议(protocol)或数据库行中的其他地方获得的序列号或其他任何内容,或者它可能是随机数)。然后,您使用 ECDH 生成 key 并使用它来加密您的数据。这将为您提供所需的 16 字节加密数据长度,但它并不是完全不对称的:加密器还能够解密消息(同样:这在您的应用程序中可能是也可能不是问题)。

Static-ephemeral 有点不同:这里加密器生成一个临时(临时)EC key 对。然后,他将此 key 对与接收方的公钥一起使用,生成一个可用于加密数据的 key 。最后,他将临时 key 对的公钥与加密数据一起发送给接收方。这可能更适合您的应用程序,但是使用 ECDH-256 和 AES 的完整加密数据现在将是 2*32+16=80 字节(正如 GregS 指出的那样,您可以通过仅发送公共(public)的 x 坐标来节省 32 字节-键,但我不相信 .NET 公开了重新计算 y 坐标的功能)。

这是一个小类,可以执行静态-静态 ECDH:

public static class StaticStaticDiffieHellman
{
private static Aes DeriveKeyAndIv(ECDiffieHellmanCng privateKey, ECDiffieHellmanPublicKey publicKey, byte[] nonce)
{
privateKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
privateKey.HashAlgorithm = CngAlgorithm.Sha256;
privateKey.SecretAppend = nonce;
byte[] keyAndIv = privateKey.DeriveKeyMaterial(publicKey);
byte[] key = new byte[16];
Array.Copy(keyAndIv, 0, key, 0, 16);
byte[] iv = new byte[16];
Array.Copy(keyAndIv, 16, iv, 0, 16);

Aes aes = new AesManaged();
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;

return aes;
}

public static byte[] Encrypt(ECDiffieHellmanCng privateKey, ECDiffieHellmanPublicKey publicKey, byte[] nonce, byte[] data){
Aes aes = DeriveKeyAndIv(privateKey, publicKey, nonce);
return aes.CreateEncryptor().TransformFinalBlock(data, 0, data.Length);
}

public static byte[] Decrypt(ECDiffieHellmanCng privateKey, ECDiffieHellmanPublicKey publicKey, byte[] nonce, byte[] encryptedData){
Aes aes = DeriveKeyAndIv(privateKey, publicKey, nonce);
return aes.CreateDecryptor().TransformFinalBlock(encryptedData,0, encryptedData.Length);
}
}

// Usage:

ECDiffieHellmanCng key1 = new ECDiffieHellmanCng();
ECDiffieHellmanCng key2 = new ECDiffieHellmanCng();

byte[] data = Encoding.UTF8.GetBytes("TestTestTestTes");
byte[] nonce = Encoding.UTF8.GetBytes("whatever");

byte[] encryptedData = StaticStaticDiffieHellman.Encrypt(key1, key2.PublicKey, nonce, data);

Console.WriteLine(encryptedData.Length); // 16

byte[] decryptedData = StaticStaticDiffieHellman.Decrypt(key2, key1.PublicKey, nonce, encryptedData);

Console.WriteLine(Encoding.UTF8.GetString(decryptedData));

关于c# - .NET 中的最小消息大小公钥加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3196297/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com