加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – .NET中最小的邮件大小公钥加密

发布时间:2020-12-15 17:37:46 所属栏目:百科 来源:网络整理
导读:我想使用公共密钥加密系统将很少的数据(15个字节精确地)加密到尽可能短的位置(最佳不超过16个字节)的消息. 标准的公共密钥系统RSA不幸地生成与其密钥一样大的消息,大约是100字节,这取决于密钥大小. 为了使事情更加困难,我只能使用.NET框架库,即没有第三方.
我想使用公共密钥加密系统将很少的数据(15个字节精确地)加密到尽可能短的位置(最佳不超过16个字节)的消息.

标准的公共密钥系统RSA不幸地生成与其密钥一样大的消息,大约是100字节,这取决于密钥大小.
为了使事情更加困难,我只能使用.NET框架库,即没有第三方.

我已经在维基百科上看过一些关于椭圆曲线密码术的文章,并且文本似乎表明,键的大小通常比RSA密钥短得多.

这是否也转化为短信?可以使用.NET ECDiffieHellmanCng类来消息/加密吗?它似乎具有不同的类结构,然后就是说,RSA或对称密码.

解决方法

您可以使用ECDiffieHellman加密消息.您有两个选项:静态ECDH和静态临时ECDH:

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

静态短暂有点不同:加密器生成一个临时(短暂的)EC关键字.然后他将这个密钥对与接收器公钥一起使用,以生成可用于加密数据的秘密密钥.最后他将短信关键字的公钥与加密数据一起发送给接收者.这可能更适合您的应用程序,但完整的加密数据现在将使用ECDH-256和AES为2 * 32 16 = 80字节(如GregS注释,只能发送公钥的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,key,16);
    byte[] iv = new byte[16];
    Array.Copy(keyAndIv,16,iv,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,byte[] nonce,byte[] data){
    Aes aes = DeriveKeyAndIv(privateKey,publicKey,nonce);
    return aes.CreateEncryptor().TransformFinalBlock(data,data.Length);
  }

  public static byte[] Decrypt(ECDiffieHellmanCng privateKey,byte[] encryptedData){
    Aes aes = DeriveKeyAndIv(privateKey,nonce);
    return aes.CreateDecryptor().TransformFinalBlock(encryptedData,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,encryptedData);

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读