【问题标题】:Error in password decryption密码解密错误
【发布时间】:2012-09-25 06:33:04
【问题描述】:

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

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=

【问题讨论】:

  • 你根本没有加密...编码只是关于 ANSI/UTF8/... 表示。
  • 这段代码运行良好。没有错误。你确定你用 "cHJhYnU=" 参数调用 Decryptdata 方法吗?
  • 我建议您查看密码中的one way hashing,让能够解密密码的代码也允许任何攻击者这样做。
  • 拜托,拜托,请阅读以下内容:codinghorror.com/blog/2007/09/…

标签: c# .net encryption


【解决方案1】:

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

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

【讨论】:

  • 显然在代码中,他没有向我们展示。这是我基于运行他的代码的假设。
【解决方案2】:

我们没有保存加密的用户密码并对其进行解密以执行身份验证,而是将密码保存为加盐散列,每次存储新密码时都会自动生成盐(盐和散列存储在数据库)。

为了验证登录尝试,我们为登录期间提供的密码生成哈希值,但使用最初设置密码时存储的盐值。然后验证登录,只需比较两个哈希值。

例如,如果您选择 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
}

【讨论】:

  • 我们通常在网站上推荐PBKDF2、bcrypt 或 scrypt,Justin T。而且散列与加密不同。
  • 我很欣赏哈希和加密是不同的,但我想你会错过阅读我的帖子,因为我正在展示加密的替代方案。
  • 问题更多在于方法名称,它们可能会使读者感到困惑。
  • @owlstead Fair 大喊,我知道那会是多么令人困惑。
【解决方案3】:
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;
        }

【讨论】:

  • 欢迎来到Stack Overflow!请不要给出纯粹的代码答案,而是解释为什么这段代码回答了提出的问题。参考How to Answer...
猜你喜欢
  • 2017-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 2019-10-24
  • 2018-03-11
相关资源
最近更新 更多