【问题标题】:Creating a SHA hash and salt and the bytes have strange characters in them创建一个 SHA 哈希和盐,字节中有奇怪的字符
【发布时间】:2016-05-18 02:47:10
【问题描述】:

我一直在研究一些密码学,我需要创建一个新的 SHA-2 (sha256) 系统,在该系统中我生成新的 salt 和 hash ,所以 hash 将基于用户输入的密码 + 新创建的 salt,因为我明白它。但是,由于我下载了一个示例项目,在我玩过的所有 sha-1 和 sha-2 代码中,我从未见过中文符号,所以我有点担心和困惑

这是代码,

    // utilty function to convert byte[] to string        
    public static string GetString(byte[] bytes)
    {
        char[] chars = new char[bytes.Length / sizeof(char)];
        System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }

传入的字节没有任何奇怪的字符,这是什么原因造成的?

截图

bytes 参数是 byte[24] .... [0] = 20 ,1 = 101 等..只是正常的外观。所以它似乎发生在这条线上 System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);

【问题讨论】:

    标签: c# hash byte sha


    【解决方案1】:

    您刚刚发现了一些 unicode 字符。我经常看到使用 UTF8 而不是 unicode,如下所示:

    var toString = System.Text.Encoding.UTF8.GetString(yourByteArray);
    var backToBytes = System.Text.Encoding.UTF8.GetBytes(toString);
    

    编辑

    这是一个控制台程序示例,它使用了我在网上搜索最佳实践示例后编写的 AES 加密/解密包装器。

    namespace Sandbox
    {
        class Program
        {
            static void Main(string[] args)
            {
                var originString = "This is some example text";
    
                var originBytes = System.Text.Encoding.UTF8.GetBytes(originString);
    
                var aes = new AesCryptoServiceProvider {KeySize = 256};
                aes.GenerateIV();
                aes.GenerateKey();
                var vectorBytes = aes.IV;
                var keyBytes = aes.Key;
    
                //Not going to use these in the code, but here's how to get the values if you
                //Want to save them off.
                var vectorString = System.Text.Encoding.UTF8.GetString(vectorBytes);
                var keyString = System.Text.Encoding.UTF8.GetString(keyBytes);
    
                var encryptedBytes = EncryptionService.Encrypt(keyBytes, vectorBytes, originBytes);
    
                var encyptedString = System.Text.Encoding.UTF8.GetString(encryptedBytes);
    
                var decryptedBytes = EncryptionService.Decrypt(keyBytes, vectorBytes, encryptedBytes);
    
                var decryptedString = System.Text.Encoding.UTF8.GetString(decryptedBytes);
    
                Console.WriteLine($"Origin:\t\t {originString}");
                Console.WriteLine($"Vector:\t\t {vectorString}");
                Console.WriteLine($"Key:\t\t {keyString}");
                Console.WriteLine($"Encrypted:\t {encyptedString}");
                Console.WriteLine($"Decrypted:\t {decryptedString}");
    
                Console.ReadLine();
    
            }
        }
    
        public static class EncryptionService
        {
            public static byte[] Encrypt(byte[] key, byte[] vector, byte[] input)
            {
                if (key.Length == 0)
                    throw new ArgumentException("Cannot encrypt with empty key");
    
                if (vector.Length == 0)
                    throw new ArgumentException("Cannot encrypt with empty vector");
    
                if (input.Length == 0)
                    throw new ArgumentException("Cannot encrypt empty input");
    
                var unencryptedBytes = input;
    
                using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider { Key = key, IV = vector })
                using (ICryptoTransform encryptor = aes.CreateEncryptor())
                using (MemoryStream ms = new MemoryStream())
                using (CryptoStream writer = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    writer.Write(unencryptedBytes, 0, unencryptedBytes.Length);
                    writer.FlushFinalBlock();
                    var byteArray = ms.ToArray();
    
                    if (byteArray.Length == 0)
                        throw new Exception("Attempted to encrypt but encryption resulted in a byte array of 0 length.");
    
                    return byteArray;
                }
            }
    
    
            public static byte[] Decrypt(byte[] key, byte[] vector, byte[] encrypted)
            {
                if (key.Length == 0)
                    throw new ArgumentException("Cannot encrypt with empty key");
    
                if (vector.Length == 0)
                    throw new ArgumentException("Cannot encrypt with empty vector");
    
                if (encrypted == null || encrypted.Length == 0)
                    throw new ArgumentException("Cannot decrypt empty or null byte array");
    
                byte[] unencrypted;
    
                using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider { Key = key, IV = vector })
                using (ICryptoTransform decryptor = aes.CreateDecryptor(key, vector))
                using (MemoryStream ms = new MemoryStream(encrypted))
                using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                {
                    var decrypted = new byte[encrypted.Length];
                    var bytesRead = cs.Read(decrypted, 0, encrypted.Length);
    
                    return decrypted.Take(bytesRead).ToArray();
                }
    
            }
        }
    }
    

    【讨论】:

    • 实用程序类中的那些方法是不是在重新发明轮子?所以我应该用你的代码代替我的代码?你能解释一下在哪里以及如何实施吗?
    • codeproject.com/Articles/608860/… 是我找到示例仅供参考的地方
    • 因此,除非您要获得一些性能优势(我怀疑您会在这个级别上找到一些东西),否则我会说您的方法是不需要的,您正在重新发明轮子。在我自己的一个项目中实施 SHA-256 时,我使用了这些确切的方法。
    • 我应该把这些代码行放在哪里? var toString = System.Text.Encoding.UTF8.GetString(yourByteArray); var backToBytes = System.Text.Encoding.UTF8.GetBytes(toString);
    • 非常感谢,这很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2017-05-04
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2021-11-27
    • 1970-01-01
    相关资源
    最近更新 更多