)使用Vernam(維爾南/弗納姆)演算法實現檔案加密解密[C#]

來源:互聯網
上載者:User

原文:使用Vernam(維爾南/弗納姆)演算法實現檔案加密解密[C#]

 

本文介紹如何通過Gilbert Sandford Vernam的演算法實現一個簡潔而又穩定的檔案加密解密類。通過此類加密的資料是絕對無法在沒有密鑰的情況下被破解的。它的基本原理是,需要有一個需要加密的明文和一個隨機產生的解密鑰匙檔案。然後使用這兩個檔案組合起來產生密文:(明文) 組合 (密鑰) = 加密後的密文。
使用Vernam密碼編譯演算法,經其處理的密鑰可以擁有與待加密檔案大小相同的密鑰長度,而且輸出檔案的大小相比待加密檔案無任何改變(精確到位元組)。換言之,密鑰檔案越大,加密強度越高!舉個例子,如果想加密一個5M的檔案,那麼密鑰長度將高達40,000,000位,輸出檔案大小則仍為5M。前面的數字意味著即使是夢幻配置的個人電腦,想要在“有生之年”靠窮取法破解出密碼,也是不可能完成的任務!待加密檔案類型不限,密鑰檔案也可以是任何資料:應用程式、分頁檔,或者音樂檔案,甚至是您寵物的靚照,等等...

Vernam密碼演算法:
    1、 現代密碼體制的萌芽是Vernam加密方法。
    2、Vernam密碼是美國電話電報公司的Gilbert Vernam在1917年為電報通訊設計的一種非常方便的密碼,它在近代電腦和通訊系統設計中得到了廣泛應用。
    3、Vernam密碼的明文、密鑰和密文均用二元數字序列表示。這是一種使用異或方法進行加密解密的方法。
    4、要編製Vernam密碼,只需先把明文和密鑰表示成二元序列,再把它們按位模2相加,就可得到密文。
    5、而解密只需把密文和密鑰的二元序列按位模2相加便可得到明文。
    6、開始時使用一個定長的密鑰序列,這樣產生的密文能形成有規律的反覆,易被破譯;後來採用的密鑰與明文同長,且密鑰序列只用一次,稱為“一次一密體制”。

Vernam類:

 
  1. using System; 
  2. using System.IO; 
  3.  
  4. public class Vernam 
  5.     /// <summary> 
  6.     /// Encrypts a file by the Vernam-algorithm 
  7.     /// </summary> 
  8.     /// <param name="originalFile"> 
  9.     /// Name of the file to be encrypted. Data is read from this file. 
  10.     /// </param> 
  11.     /// <param name="encryptedFile"> 
  12.     /// Name of the encrypted file. The encrypted data gets written to that file. 
  13.     /// </param> 
  14.     /// <param name="keyFile"> 
  15.     /// Name of the key file. The one time key gets written to that file. 
  16.     /// </param> 
  17.     public void EncryptFile(string originalFile, string encryptedFile, string keyFile) 
  18.     { 
  19.         // Read in the bytes from the original file: 
  20.         byte[] originalBytes; 
  21.         using (FileStream fs = new FileStream(originalFile, FileMode.Open)) 
  22.         { 
  23.             originalBytes = new byte[fs.Length]; 
  24.             fs.Read(originalBytes, 0, originalBytes.Length); 
  25.         } 
  26.  
  27.         // Create the one time key for encryption. This is done 
  28.         // by generating random bytes that are of the same lenght  
  29.         // as the original bytes: 
  30.         byte[] keyBytes = new byte[originalBytes.Length]; 
  31.         Random random = new Random(); 
  32.         random.NextBytes(keyBytes); 
  33.  
  34.         // Write the key to the file: 
  35.         using (FileStream fs = new FileStream(keyFile, FileMode.Create)) 
  36.         { 
  37.             fs.Write(keyBytes, 0, keyBytes.Length); 
  38.         } 
  39.  
  40.         // Encrypt the data with the Vernam-algorithm: 
  41.         byte[] encryptedBytes = new byte[originalBytes.Length]; 
  42.         DoVernam(originalBytes, keyBytes, ref encryptedBytes); 
  43.  
  44.         // Write the encrypted file: 
  45.         using (FileStream fs = new FileStream(encryptedFile, FileMode.Create)) 
  46.         { 
  47.             fs.Write(encryptedBytes, 0, encryptedBytes.Length); 
  48.         } 
  49.     } 
  50.     //--------------------------------------------------------------------- 
  51.     /// <summary> 
  52.     /// Decrypts a file by Vernam-algorithm 
  53.     /// </summary> 
  54.     /// <param name="encryptedFile"> 
  55.     /// Name of the encrypted file 
  56.     /// </param> 
  57.     /// <param name="keyFile"> 
  58.     /// Name of the key file. The content of this file has to be the same 
  59.     /// as the content generated while encrypting 
  60.     /// </param> 
  61.     /// <param name="decryptedFile"> 
  62.     /// Name of the decrypted file. The decrypted data gets written to this  
  63.     /// file 
  64.     /// </param> 
  65.     public void DecryptFile(string encryptedFile, string keyFile, string decryptedFile) 
  66.     { 
  67.         // Read in the encrypted bytes: 
  68.         byte[] encryptedBytes; 
  69.         using (FileStream fs = new FileStream(encryptedFile, FileMode.Open)) 
  70.         { 
  71.             encryptedBytes = new byte[fs.Length]; 
  72.             fs.Read(encryptedBytes, 0, encryptedBytes.Length); 
  73.         } 
  74.  
  75.         // Read in the key: 
  76.         byte[] keyBytes; 
  77.         using (FileStream fs = new FileStream(keyFile, FileMode.Open)) 
  78.         { 
  79.             keyBytes = new byte[fs.Length]; 
  80.             fs.Read(keyBytes, 0, keyBytes.Length); 
  81.         } 
  82.  
  83.         // Decrypt the data with the Vernam-algorithm: 
  84.         byte[] decryptedBytes = new byte[encryptedBytes.Length]; 
  85.         DoVernam(encryptedBytes, keyBytes, ref decryptedBytes); 
  86.  
  87.         // Write the decrypted file: 
  88.         using (FileStream fs = new FileStream(decryptedFile, FileMode.Create)) 
  89.         { 
  90.             fs.Write(decryptedBytes, 0, decryptedBytes.Length); 
  91.         } 
  92.     } 
  93.     //--------------------------------------------------------------------- 
  94.     /// <summary> 
  95.     /// Computes the Vernam-encryption/decryption 
  96.     /// </summary> 
  97.     /// <param name="inBytes"></param> 
  98.     /// <param name="keyBytes"></param> 
  99.     /// <param name="outBytes"></param> 
  100.     private void DoVernam(byte[] inBytes, byte[] keyBytes, ref byte[] outBytes) 
  101.     { 
  102.         // Check arguments: 
  103.         if ((inBytes.Length != keyBytes.Length) || 
  104.             (keyBytes.Length != outBytes.Length)) 
  105.             throw new ArgumentException("Byte-array are not of same length"); 
  106.  
  107.         // Encrypt/decrypt by XOR: 
  108.         for (int i = 0; i < inBytes.Length; i++) 
  109.             outBytes[i] = (byte)(inBytes[i] ^ keyBytes[i]); 
  110.     } 

使用範例:

 
  1. class Program 
  2.     static void Main(string[] args) 
  3.     { 
  4.         Vernam vernam = new Vernam(); 
  5.  
  6.         // Test with an image: 
  7.         vernam.EncryptFile("Image.gif", "Image_encrypted.gif", "Key01.dat"); 
  8.         vernam.DecryptFile("Image_encrypted.gif", "Key01.dat", "Image_decrypted.gif"); 
  9.  
  10.         // Test with text file: 
  11.         vernam.EncryptFile("Text.txt", "Text_encrypted.txt", "Key02.dat"); 
  12.         vernam.DecryptFile("Text_encrypted.txt", "Key02.dat", "Text_decrypted.txt"); 
  13.  
  14.         // Test with pdf file: 
  15.         vernam.EncryptFile("Text.pdf", "Text_encrypted.pdf", "Key03.dat"); 
  16.         vernam.DecryptFile("Text_encrypted.pdf", "Key03.dat", "Text_decrypted.pdf"); 
  17.     } 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.