1

我正要使用 One Time Pad 构建一个简单的聊天应用程序。我已经制定了算法,并且为了加密消息,我需要某种双方相同的密钥材料。密钥材料的分发应该通过物理接触(例如 USB 加密狗)进行。所以我想做一些非常大的随机密钥文件,两个客户端可以用来通信。所以我的问题是:

  • 我需要一个非常安全的随机数/字符串生成器,你知道我可以在 C# 中使用什么好的吗?
  • 当我使用这么大的文件时,我该如何避免将整个文件加载到内存中,因为我打算读取一大块关键材料(例如 1 MB),然后在读取时将其从文件中删除,所以相同的密钥不会被使用两次。
4

3 回答 3

2

我可能应该从这个开始:我认为这是一个娱乐或锻炼项目 - 而不是试图创建真正安全的东西。

  1. 正如owlstead所说:使用RNGCryptoServiceProvider
  2. 如果反向使用,从文件中删除使用过的密钥材料会容易得多。如果您需要加密 1024 个字节,请从文件中读取最后 1024 个字节并截断它。简化:

 

byte[] Encrypt(byte[] plain){
  using (FileStream keyFile = new FileStream(FileName, FileMode.Open))
  {
    keyFile.Seek(-plain.Length, SeekOrigin.End);
    byte[] key = new byte[plain.Length];
    keyFile.Read(key, 0, plain.Length);    
    byte[] encrypted = new byte[plain.Length];
    for(int i=0;i<plain.Length;i++){
      encrypted[i] = (byte) (plain[i] ^ key[plain.Length - 1 - i]);
    } 
    keyFile.SetLength(keyFile.Length - plain.Length);   
    return encrypted;
  }      
}
于 2012-06-08T09:56:32.610 回答
0

您设计的几乎可以肯定不是一次性便笺簿。大量真正随机字节的生成绝非易事。如果你真的必须走这条路,你真的应该在硬件卡上花费几千美元。即使是加密质量的 C# RNG 也无法生成那种数量的真正随机数据。它可以足够安全地生成短密钥,但没有足够的熵输入来生成大量真正的随机数据。一旦熵用完,它的输出就会恢复为伪随机,并且您不再拥有 One Time Pad。

正如@owlstead 所说,在 CBC 或 CTR 模式下使用 AES。这是安全的,容易获得的,不是由业余爱好者设计的。

于 2012-06-08T12:46:37.633 回答
0

您正在尝试解决一个已经解决的问题:使用 AES 几乎可以肯定与使用 One Time Pad 一样安全。在这种情况下,您的密钥变为 16 个字节(尽管您需要一个 NONCE 或 IV,具体取决于模式)。

  1. 您需要使用安全的随机数生成器RNGCryptoServiceProvider
  2. 使用MemoryMappedFile将文件读入内存。

只是(原子地)将偏移量存储在文件中。例如,使用同一个文件中的前 8 个字节来存储一个 ulong 类型,这样您就可以在需要时进行同步。如果您真的需要,除了使用的字节之外,您还可以在文件中写入零。请注意,例如使用 SSD,您实际上可能不会覆盖物理数据。

于 2012-06-07T21:15:16.840 回答