具有大型随机密钥文件的One Time Pad聊天应用程序

时间:2012-06-07 20:45:40

标签: c# encryption random cryptography

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

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

3 个答案:

答案 0 :(得分:2)

我应该从这开始:我认为这是一个有趣的或锻炼项目 - 而不是尝试创造真正安全的东西。

  1. 正如owlstead所说:使用RNGCryptoServiceProvider
  2. 如果您反向使用,则从文件中删除使用过的密钥材料要容易得多。如果需要加密1024个字节,请从文件中读取最后1024个字节并将其截断。简化:
  3. 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;
      }      
    }
    

答案 1 :(得分:0)

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

  1. 您需要使用安全随机数生成器RNGCryptoServiceProvider
  2. 使用MemoryMappedFile将文件读入内存。
  3. 只是(原子地)将偏移量存储在文件中。例如。使用同一文件中的前8个字节来存储ulong类型,以便在需要时进行同步。除了你真正想要的字节数之外,你可以在文件中写入零。请注意,例如使用SSD,您实际上可能无法覆盖物理数据。

答案 2 :(得分:0)

你设计的几乎肯定不是一次性垫。生成大量真正的随机字节远非繁琐的任务。如果你真的必须沿着那条路走下去,那么你应该花几千美元在硬件卡上。即使是加密质量的C#RNG也无法生成那种真正的随机数据。它可以足够安全地生成短密钥,但没有足够的熵输入来生成大量真正的随机数据。一旦熵耗尽,其输出将恢复为伪随机,您不再拥有一次性打击垫。

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