2012-11-20 138 views
1

我有一個程序,我在其中編寫和讀取配置文件。當我編寫時,我使用vb.net中的RijndaelManaged對象加密整個文件,當我讀取密鑰和init向量時使用相同的值進行解密。在vb.net加密/解密並不總是返回相同的值

它在我的開發機器和其他許多設備上都能正常工作。但是,某些PC無法使用相同的程序加密/解密文件。

在這個加密對象中是否有防止它的任何東西,你會推薦使用什麼呢?

感謝

編輯:這裏是我使用的加密和解密的代碼:從我所看到的,如果我從我的主機加密字節,我可以從任何PC decypt它。但是,如果我從其他PC上加密字節,我無法從任何PC解密。另外,當我查看文件的內容時,它們看起來並不一樣。請注意,我常用的方法是從文件(通常是XML)創建一個內存流,然後加密/解密。

Public Shared Function EncryptBytes(ByVal strContenu() As Byte, ByVal initVectorBytes() As Byte, ByVal saltValueBytes() As Byte) As Byte() 

    ' Convert our plaintext into a byte array. 
    ' Let us assume that plaintext contains UTF8-encoded characters. 
    Dim plainTextBytes As Byte() = strContenu 
    'plainTextBytes = System.Text.Encoding.Unicode.GetBytes(strMessage) 

    Dim strPassPhrase As String = "d%6&?76dhd8?532LDhds8!7?&?8&?dhcv77" 

    Dim strHashAlgorithm As String = "SHA1" 

    Dim intPswdIterations As Integer = 2 

    ' First, we must create a password, from which the key will be derived. 
    ' This password will be generated from the specified passphrase and 
    ' salt value. The password will be created using the specified hash 
    ' algorithm. Password creation can be done in several iterations. 
    Dim password As PasswordDeriveBytes 
    password = New PasswordDeriveBytes(strPassPhrase, _ 
             saltValueBytes, _ 
             strHashAlgorithm, _ 
             intPswdIterations) 

    ' Use the password to generate pseudo-random bytes for the encryption 
    ' key. Specify the size of the key in bytes (instead of bits). 
    Dim keyBytes As Byte() 
    keyBytes = password.GetBytes(32) 

    ' Create uninitialized Rijndael encryption object. 
    Dim symmetricKey As RijndaelManaged 
    symmetricKey = New RijndaelManaged() 

    ' It is reasonable to set encryption mode to Cipher Block Chaining 
    ' (CBC). Use default options for other symmetric key parameters. 
    symmetricKey.Mode = CipherMode.CBC 

    ' Generate encryptor from the existing key bytes and initialization 
    ' vector. Key size will be defined based on the number of the key 
    ' bytes. 
    Dim encryptor As ICryptoTransform 
    encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes) 

    ' Define memory stream which will be used to hold encrypted data. 
    Dim memoryStream As System.IO.MemoryStream 
    memoryStream = New System.IO.MemoryStream() 

    ' Define cryptographic stream (always use Write mode for encryption). 
    Dim cryptoStream As CryptoStream 
    cryptoStream = New CryptoStream(memoryStream, _ 
            encryptor, _ 
            CryptoStreamMode.Write) 
    ' Start encrypting. 
    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length) 

    ' Finish encrypting. 
    cryptoStream.FlushFinalBlock() 

    ' Convert our encrypted data from a memory stream into a byte array. 
    Dim cipherTextBytes As Byte() 
    cipherTextBytes = memoryStream.ToArray() 

    ' Close both streams. 
    memoryStream.Close() 
    cryptoStream.Close() 

    ' Convert encrypted data into a base64-encoded string. 
    'Dim cipherText As String 
    'cipherText = 
    Return cipherTextBytes 

    ' Return encrypted string. 
    'Return cipherText 

End Function 

Public Shared Function DecryptBytes(ByVal strContenuEncrypte() As Byte, ByVal initVectorBytes() As Byte, ByVal saltValueBytes() As Byte) As Byte() 

    ' Convert strings defining encryption key characteristics into byte 
    ' arrays. Let us assume that strings only contain ASCII codes. 
    ' If strings include Unicode characters, use Unicode, UTF7, or UTF8 
    ' encoding. 

    ' Convert our ciphertext into a byte array. 
    Dim cipherTextBytes As Byte() = strContenuEncrypte 

    Dim strPassPhrase As String = "d%6&?76dhd8DSDhds8!7?&?8&?dhcv77" 

    Dim strHashAlgorithm As String = "SHA1" 

    Dim intPswdIterations As Integer = 2 

    ' First, we must create a password, from which the key will be 
    ' derived. This password will be generated from the specified 
    ' passphrase and salt value. The password will be created using 
    ' the specified hash algorithm. Password creation can be done in 
    ' several iterations. 
    Dim password As PasswordDeriveBytes 
    password = New PasswordDeriveBytes(strPassPhrase, _ 
             saltValueBytes, _ 
             strHashAlgorithm, _ 
             intPswdIterations) 

    ' Use the password to generate pseudo-random bytes for the encryption 
    ' key. Specify the size of the key in bytes (instead of bits). 
    Dim keyBytes As Byte() 
    keyBytes = password.GetBytes(32) 

    ' Create uninitialized Rijndael encryption object. 
    Dim symmetricKey As RijndaelManaged 
    symmetricKey = New RijndaelManaged() 

    ' It is reasonable to set encryption mode to Cipher Block Chaining 
    ' (CBC). Use default options for other symmetric key parameters. 
    symmetricKey.Mode = CipherMode.CBC 

    ' Generate decryptor from the existing key bytes and initialization 
    ' vector. Key size will be defined based on the number of the key 
    ' bytes. 
    Dim decryptor As ICryptoTransform 
    decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes) 

    ' Define memory stream which will be used to hold encrypted data. 
    Dim memoryStream As System.IO.MemoryStream 
    memoryStream = New System.IO.MemoryStream(cipherTextBytes) 

    ' Define memory stream which will be used to hold encrypted data. 
    Dim cryptoStream As CryptoStream 
    cryptoStream = New CryptoStream(memoryStream, _ 
            decryptor, _ 
            CryptoStreamMode.Read) 

    ' Since at this point we don't know what the size of decrypted data 
    ' will be, allocate the buffer long enough to hold ciphertext; 
    ' plaintext is never longer than ciphertext. 
    Dim plainTextBytes As Byte() 
    ReDim plainTextBytes(cipherTextBytes.Length) 

    ' Start decrypting. 
    Dim decryptedByteCount As Integer 
    decryptedByteCount = cryptoStream.Read(plainTextBytes, _ 
              0, _ 
              plainTextBytes.Length) 

    ' Close both streams. 
    memoryStream.Close() 
    cryptoStream.Close() 

    ' Convert decrypted data into a string. 
    ' Let us assume that the original plaintext string was UTF8-encoded. 
    Dim plainText As String 
    plainText = System.Text.Encoding.Unicode.GetString(plainTextBytes, _ 
             0, _ 
             decryptedByteCount) 

    ' Return decrypted string. 
    Return plainTextBytes 


End Function 
+1

字節你能後的代碼爲您的加密算法? – nerdybeardo

回答

1

如果使用,而不是正常的.NET作爲運行時單聲道,然後PasswordDeriveBytes將爲高於20 PasswordDeriveBytes使用未知的,專有的,非確定性的,破碎,加密不安全方法任何輸出當請求多個輸出失敗比散列輸出可以在PasswordDeriveBytes內提供。 This has been marked as no-fix by the Mono developers.

最好的辦法是升級到Rfc2898DeriveBytes,它實現PBKDF2而不是PBKDF1。 PBKDF2定義瞭如何擴展輸出量,因此所有的實現都應該按照規定運行。

如果您需要比散列函數提供的輸出更多的輸出,那麼在PBKDF2的輸出上使用KBFDF(例如HKDF)會更安全。 PKBDF2需要另外一整輪才能創建更多數據,這可能有利於攻擊者而不是普通用戶,並且會根據請求的字節數來增加CPU負載的兩倍或三倍。

[編輯]

還要注意使用的PasswordDeriveBytes,需要一個密碼沒有指定字符編碼是構造函數,所以你最好把它轉換成字節將其送入前構造函數。

根據大多數觀察,儘管兩者似乎都使用UTF-8,但要注意其他運行時(如Java)在這方面可能會有所不同。

0

胡亂猜測:你在寫作和閱讀文本模式的文件嗎?當加密數據碰巧包含0x1A(EOF,ctrl-z)讀數可能會提前停止,並且您解密爲幾個字節。

+0

該文件本身是一個XML文件,在加密到文件之前我將其寫入內存流。這怎麼能從一臺PC到另一臺? –

+0

「加密到文件」是什麼意思?您可以加密數據或將數據保存到文件。所有機器上的加密數據是否相同或使用不同的加密密鑰。正如Moe所建議的:請張貼一些相關的代碼。 – Jeff

0

你不能上傳120Gb文件到一個字節()。或者你有一些瘋狂的機器。 嘗試上傳字節到RAM

Dim fStream As FileStream = New FileStream("Encrypted.Encrypted", FileMode.Create) 
     Dim cryptoStream As New CryptoStream(fStream, Encryptor, CryptoStreamMode.Write) 
     Using UploadFile As FileStream = New FileStream(OpenfileDialog.FileName, FileMode.Open) 
      For i = 0 To UploadFile.Length - 1 
       Dim NewByte As New Byte 
       NewByte = UploadFile.ReadByte 
       cryptoStream.WriteByte(NewByte) 
      Next 
     End Using 

     cryptoStream.FlushFinalBlock() 
     cryptoStream.Close() 
     fStream.Close()