2013-07-26 17 views
0

我使用Rijndael算法來加密字符串(用戶密碼),但是當我解密它們時,它返回我「System.SecureString」 ,而不是我的解密密碼。解密與Rijndael字符串返回「System.SecureString」(作爲字符串),但不是字符串

我使用這個基本代碼:

public static string DecryptString(string cipherText, string password) 
    { 
     byte[] key, iv; 
     Rfc2898DeriveBytes rfcDb = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(password)); 
     key = rfcDb.GetBytes(16); 
     iv = rfcDb.GetBytes(16); 

     byte[] cipheredData = Convert.FromBase64String(cipherText); 

     RijndaelManaged rijndael = new RijndaelManaged(); 
     rijndael.Mode = CipherMode.CBC; 

     ICryptoTransform decryptor = rijndael.CreateDecryptor(key, iv); 
     MemoryStream ms = new MemoryStream(cipheredData); 
     CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read); 

     byte[] plainTextData = new byte[cipheredData.Length]; 

     int decryptedByteCount = cs.Read(plainTextData, 0, plainTextData.Length); 

     ms.Close(); 
     cs.Close(); 

     return Encoding.UTF8.GetString(plainTextData, 0, decryptedByteCount); 
    } 

真正的問題是,它送我回來「System.SecureString」,我不能做任何事情。

我認爲它來自轉換在最後,但我真的不知道該如何改變(似乎不錯BTW)

return Encoding.UTF8.GetString(plainTextData, 0, decryptedByteCount); 

所以,如果你有一個想法或工作代碼示例,我很感興趣。

有一個愉快的一天

+0

您問題的原因在您發佈的代碼之外。沒有安全的字符串。我懷疑你在某處調用'password.ToString()',試圖從'SecureString'轉換爲'String'。但是你不能像那樣轉換。 – CodesInChaos

回答

1

我已經在過去實施的Rijndael算法,這裏是我的版本,如果這是任何幫助:

private static string Encrypt(string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) 
     { 
      // Convert strings into byte arrays. 
      // Let us assume that strings only contain ASCII codes. 
      // If strings include Unicode characters, use Unicode, UTF7, or UTF8 
      // encoding. 
      var initVectorBytes = Encoding.ASCII.GetBytes(initVector); 
      var saltValueBytes = Encoding.ASCII.GetBytes(saltValue); 

      // Convert our plaintext into a byte array. 
      // Let us assume that plaintext contains UTF8-encoded characters. 
      var plainTextBytes = Encoding.UTF8.GetBytes(plainText); 

      // 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. 
      var password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations); 

      // Use the password to generate pseudo-random bytes for the encryption 
      // key. Specify the size of the key in bytes (instead of bits). 
      var keyBytes = password.GetBytes(keySize/8); 

      // Create uninitialized Rijndael encryption object. 

      // It is reasonable to set encryption mode to Cipher Block Chaining 
      // (CBC). Use default options for other symmetric key parameters. 
      var symmetricKey = new RijndaelManaged { 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. 
      var encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes); 

      // Define memory stream which will be used to hold encrypted data. 
      var memoryStream = new MemoryStream(); 

      // Define cryptographic stream (always use Write mode for encryption). 
      var 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. 
      var cipherTextBytes = memoryStream.ToArray(); 

      // Close both streams. 
      memoryStream.Close(); 
      cryptoStream.Close(); 

      // Convert encrypted data into a base64-encoded string. 
      var cipherText = Convert.ToBase64String(cipherTextBytes); 

      // Return encrypted string. 
      return cipherText; 
     } 


private static string Decrypt(string cipherText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) 
     { 
      // 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. 
      var initVectorBytes = Encoding.ASCII.GetBytes(initVector); 
      var saltValueBytes = Encoding.ASCII.GetBytes(saltValue); 

      // Convert our ciphertext into a byte array. 
      var cipherTextBytes = Convert.FromBase64String(cipherText); 

      // 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. 
      var password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations); 

      // Use the password to generate pseudo-random bytes for the encryption 
      // key. Specify the size of the key in bytes (instead of bits). 
      var keyBytes = password.GetBytes(keySize/8); 

      // Create uninitialized Rijndael encryption object. 
      // It is reasonable to set encryption mode to Cipher Block Chaining 
      // (CBC). Use default options for other symmetric key parameters. 
      var symmetricKey = new RijndaelManaged { 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. 
      var decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes); 

      // Define memory stream which will be used to hold encrypted data. 
      var memoryStream = new MemoryStream(cipherTextBytes); 

      // Define cryptographic stream (always use Read mode for encryption). 
      var 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. 
      var plainTextBytes = new byte[cipherTextBytes.Length]; 

      // Start decrypting. 
      var 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. 
      var plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 

      // Return decrypted string. 
      return plainText; 
     } 

public static string EncryptData(string encryptText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) 
{ 
    return Encrypt(encryptText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize); 
} 

public static string DecryptData(string decryptText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations, string initVector, int keySize) 
{ 
    return Decrypt(decryptText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize); 
} 

我再有這樣的調入上述方法的一些公共方法...

public static string EncryptData(string encryptText) 
{ 
    return EncryptionHelper.EncryptData(encryptText, ConfigHelper.PassPhrase, ConfigHelper.SaltValue, ConfigHelper.HashAlgorithm, ConfigHelper.PasswordIterations, ConfigHelper.InitVector, ConfigHelper.KeySize); 
} 

public static string DecryptData(string decryptText) 
{ 
    return EncryptionHelper.DecryptData(decryptText, ConfigHelper.PassPhrase, ConfigHelper.SaltValue, ConfigHelper.HashAlgorithm, ConfigHelper.PasswordIterations, ConfigHelper.InitVector, ConfigHelper.KeySize); 
} 

然後我在配置文件中有這些...

<add key="passPhrase" value=""/> 
<add key="saltValue" value=""/> 
<add key="hashAlgorithm" value="SHA1"/> 
<add key="passwordIterations" value="5"/> 
<add key="initVector" value=""/> 
<add key="keySize" value="256"/> 
+0

所以我的代碼是正確的,我只是愚蠢的。 我發送我的密碼passwordBox.SecurePassword而不是passwordBox.Password我的功能。所以它發送「System.SecurePassword」(爲什麼?,idk)而不是我的密碼。所以我發現「System.SecurePassword」是正常的,因爲它實際上是被加密的。 所以,謝謝你christiandev,我的代碼是正確的,但它是你的,這讓我意識到這一點 祝你有美好的一天 – crocteamgg

+0

@crocteamgg請發佈作爲一個答案,這是足夠的人做同樣的事情。這根本不算什麼。 –

+0

什麼是-1? – christiandev