2017-03-16 87 views
1

我的加密和解密方法:解密字節數組SymmetricAlgorithm和CryptoStream的

private static SymmetricAlgorithm GetAlgorithm(string password) 
{ 
    using (Rijndael algorithm = Rijndael.Create()) 
    { 
     using (Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(password, new byte[] 
     { 
      0x53, 0x6f, 0x64, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x68, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x65 
     })) 
     { 
      algorithm.Padding = PaddingMode.ISO10126; 
      algorithm.Key = rdb.GetBytes(32); 
      algorithm.IV = rdb.GetBytes(16); 
     } 
     return algorithm; 
    } 
} 

public static byte[] EncryptBytes(byte[] clearBytes, string password) 
{ 
    ICryptoTransform encryptor; 
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password)) 
     encryptor = algorithm.CreateEncryptor(); 
    using (MemoryStream ms = new MemoryStream()) 
    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) 
    { 
     cs.Write(clearBytes, 0, clearBytes.Length); 
     cs.FlushFinalBlock(); 
     return ms.ToArray(); 
    } 
} 

public static byte[] DecryptBytes(byte[] cipherBytes, string password) 
{ 
    ICryptoTransform decryptor; 
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password)) 
     decryptor = algorithm.CreateDecryptor(); 
    using (MemoryStream ms = new MemoryStream()) 
    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write)) 
    { 
     cs.Write(cipherBytes, 0, cipherBytes.Length); //here is the exception thrown 
     cs.FlushFinalBlock(); 
     return ms.ToArray(); 
    } 
} 

我如何調用的方法:

byte[] prev = File.ReadAllBytes(path + sourcefile); 
byte[] enc = Encryption.EncryptBytes(prev, password); 
byte[] dec = Encryption.DecryptBytes(enc, password); 

File.WriteAllBytes(path + targetfile, dec); 

當我嘗試解密的字節數組我得到以下例外:

System.Security.Cryptography.CryptographicException 
Additional information: padding is invalid and cannot be removed 

我已經閱讀了一些可能的解決方案,但沒有一個解決了我的問題。 密鑰和IV(InitialisationVector)是相同的,當我加密和解密,所以這絕對不是原因。

+1

'GetAlgorithm'是錯誤的:您正在返回'Disposed''算法' – xanatos

+0

但我什麼時候需要配置它呢? –

+0

你在'GetAlgorithm()'的調用方法中拋棄了'算法' – xanatos

回答

2

修正方法:

錯誤:你在GetAlgorithm()處置的Rijndael algorithm。這是錯誤的:它是GetAlgorithm()必須處置algorithm(如你在做正確),主叫這裏

private static SymmetricAlgorithm GetAlgorithm(string password) 
{ 
    Rijndael algorithm = Rijndael.Create(); 

    using (Rfc2898DeriveBytes rdb = new Rfc2898DeriveBytes(password, new byte[] 
    { 
     0x53, 0x6f, 0x64, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x68, 0x6c, 0x6f, 0x72, 0x69, 0x64, 0x65 
    })) 
    { 
     algorithm.Padding = PaddingMode.ISO10126; 
     algorithm.Key = rdb.GetBytes(32); 
     algorithm.IV = rdb.GetBytes(16); 
    } 

    return algorithm; 
} 

小的警告:你不處置的ICryptoTransform

public static byte[] EncryptBytes(byte[] clearBytes, string password) 
{ 
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password)) 
    using (ICryptoTransform encryptor = algorithm.CreateEncryptor()) 
    using (MemoryStream ms = new MemoryStream()) 
    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) 
    { 
     cs.Write(clearBytes, 0, clearBytes.Length); 
     cs.FlushFinalBlock(); 
     return ms.ToArray(); 
    } 
} 

public static byte[] DecryptBytes(byte[] cipherBytes, string password) 
{ 
    using (SymmetricAlgorithm algorithm = GetAlgorithm(password)) 
    using (ICryptoTransform decryptor = algorithm.CreateDecryptor()) 
    using (MemoryStream ms = new MemoryStream()) 
    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write)) 
    { 
     cs.Write(cipherBytes, 0, cipherBytes.Length); //here is the exception thrown 
     cs.FlushFinalBlock(); 
     return ms.ToArray(); 
    } 
}