2012-09-25 56 views
0

我必须以加密格式将密码字段存储在SQL Server数据库中,并且我必须在用户登录系统时解密它。加密部分工作正常。但我解密部分的错误为“无效长度为Base-64字符数组”在行密码解密中的错误

byte[] todecode_byte = Convert.FromBase64String(encryptpwd); 

的解密模块。

private string Encryptdata(string password) 
{ 
     string encryptpwd = string.Empty; 
     byte[] encode = new byte[password.Length]; 
     encode = Encoding.UTF8.GetBytes(password); 
     encryptpwd = Convert.ToBase64String(encode); 
     return encryptpwd; 
} 

private string Decryptdata(string encryptpwd) 
{ 
     string decryptpwd = string.Empty; 
     UTF8Encoding encodepwd = new UTF8Encoding(); 
     Decoder Decode = encodepwd.GetDecoder(); 
     byte[] todecode_byte = Convert.FromBase64String(encryptpwd); //here I am getting error as "Invalid length for a Base-64 char array" 
     int charCount = Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length); 
     char[] decoded_char = new char[charCount]; 
     Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0); 
     decryptpwd = new String(decoded_char); 
     return decryptpwd; 
} 

输入数据:prabu
加密数据:cHJhYnU=

+3

你是不是加密在所有...编码是只是ANSI/UTF8/...表示。 –

+0

而这段代码运行良好。没有错误。你确定你用“cHJhYnU =”参数调用Decryptdata方法吗? –

+4

我建议你看一下密码的[单向哈希](http://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification),让代码能够解密密码,这样攻击者也可以这么做。 –

回答

0

,因为你的代码是这样的你有一个错误:

string password = "prabu"; 
    string encryptdata = Encryptdata(password); 
    string decryptdata = Decryptdata(password); 
+0

他在哪里做? – Default

+0

明显在代码中,他没有向我们展示。这是基于运行他的代码的假设。 –

0

而不是保存的加密用户密码,并解密功能执行身份验证,我们使用保存密码作为盐渍散列,其中每次要存储新密码(盐和散列存储在数据库中)时自动生成salt。

要验证登录尝试,我们为登录时提供的密码生成散列,但使用我们在初始设置密码时存储的盐。然后,要验证登录名,只需比较两个哈希值。

例如,如果您选择SHA1哈希函数:

using System; 
using System.Security.Cryptography; 

public interface ISaltedHash 
{ 
    /// <summary> 
    /// Gets the hash. 
    /// </summary> 
    string Hash 
    { 
     get; 
    } 

    /// <summary> 
    /// Gets the salt. 
    /// </summary> 
    string Salt 
    { 
     get; 
    } 
} 

public class SaltedHashProvider 
{ 
    #region Fields 

    private int m_saltLength = 6; 

    #endregion // Fields 

    #region Public Methods 

    /// <summary> 
    /// Encrypts data with the a salted SHA1 algorith. 
    /// The salt will be automatically generated. 
    /// </summary> 
    /// <param name="value">Value to be encrypted.</param> 
    /// <returns>The encrypted data.</returns> 
    public ISaltedHash EncryptWithSalt(string value) 
    { 
     string salt = CreateSalt(); 

     string hash = Encrypt(salt + value); 

     return new SaltedHash 
     { 
      Hash = hash, 
      Salt = salt 
     }; 
    } 

    /// <summary> 
    /// Encrypts data with the a salted SHA1 algorith. 
    /// </summary> 
    /// <param name="value">Value to be encrypted.</param> 
    /// <param name="salt">Salt to be used when encypting the value.</param> 
    /// <returns>The encrypted data.</returns> 
    public ISaltedHash EncryptWithSalt(string value, string salt) 
    { 
     string hash = Encrypt(salt + value); 

     return new SaltedHash 
     { 
      Hash = hash, 
      Salt = salt 
     }; 
    } 

    #endregion // Public Methods 

    #region Helper Methods 

    /// <summary> 
    /// Creates salt. 
    /// </summary> 
    /// <returns>A base64 salt string.</returns> 
    private string CreateSalt() 
    { 
     byte[] saltBlob = CreateRandomBytes(m_saltLength); 

     return Convert.ToBase64String(saltBlob); 
    } 

    /// <summary> 
    /// Encrypts data with the SHA1 algorithm. 
    /// </summary> 
    /// <param name="value">Value to be encrypted.</param> 
    /// <returns>The encrypted data.</returns> 
    private string Encrypt(string value) 
    { 
     byte[] blob = ToByteArray(value); 

     byte[] hash = ComputeHash(blob); 

     return Convert.ToBase64String(hash); 
    } 

    /// <summary> 
    /// Computes the hash value for the specified byte array. 
    /// </summary> 
    /// <param name="blob">The input to commute the hash for.</param> 
    /// <returns>The computed hash code.</returns> 
    private byte[] ComputeHash(byte[] blob) 
    { 
     return new SHA1CryptoServiceProvider().ComputeHash(blob); 
    } 

    /// <summary> 
    /// Gets a UTF8 byte array encoding for the specified character array. 
    /// </summary> 
    /// <param name="value">The input containing characters to be encoded.</param> 
    /// <returns>The UTF8 encoded array.</returns> 
    private byte[] ToByteArray(string value) 
    { 
     return System.Text.Encoding.UTF8.GetBytes(value); 
    } 

    /// <summary> 
    /// Creates a random byte array. 
    /// </summary> 
    /// <param name="length">Length of array to be generated.</param> 
    /// <returns>A random byte array.</returns> 
    private static byte[] CreateRandomBytes(int length) 
    { 
     byte[] blob = new byte[length]; 

     new RNGCryptoServiceProvider().GetBytes(blob); 

     return blob; 
    } 

    #endregion // Helper Methods 
} 
+0

我们通常推荐[PBKDF2](http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx),bcrypt或scrypt在网站上,Justin T.并且哈希不是与加密一样。 –

+0

我赞赏哈希和加密是不同的,但我想你在阅读我的文章时,因为我演示了加密的替代方案。 –

+0

问题更多的是关于方法名称,他们可能会混淆读者。 –

0
private string Decrypt(string cipherText) 
     { 
      string EncryptionKey = "MAKV2SPBNI99212"; 
      byte[] cipherBytes = Convert.FromBase64String(cipherText); 
      using (Aes encryptor = Aes.Create()) 
      { 
       Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
       encryptor.Key = pdb.GetBytes(32); 
       encryptor.IV = pdb.GetBytes(16); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(cipherBytes, 0, cipherBytes.Length); 
         cs.Close(); 
        } 
        cipherText = Encoding.Unicode.GetString(ms.ToArray()); 
       } 
      } 
      return cipherText; 
     } 
+0

欢迎来到[so]!请不要给出纯粹的代码答案,但要解释为什么这段代码回答了提出的问题。参考[答] ... – jkalden