訓練家的快寫筆記

The legend of trainer's paper


搜尋:

     關閉     
標題:MSSQL 加解密
內容:

delete from test;
insert test(title,content,USER_ID)VALUES('標題','我是內容',  convert(nvarchar(max),EncryptByPassPhrase('我是密碼',N'宗'),1) )

-- 查詢 1
select *, convert(nvarchar(max),(
              decryptByPassPhrase('我是密碼',CONVERT(varbinary(max),USER_ID,1))
)) AS [解碼後] from test


-- 查詢 2
select * From test where convert(nvarchar(max),(
              decryptByPassPhrase('我是密碼',CONVERT(varbinary(max),USER_ID,1)))) like '%宗%'



-- 查詢 3
select convert(nvarchar(max),(
              decryptByPassPhrase('我是密碼',CONVERT(varbinary(max),'0x010000001E37D75018E2988D7CA6066CA6F7C73BD2033028D17F0074',1)))) 








資料結構
ID   title           content            USER_ID                                                                                                                          [解密後]
40	標題	我是內容	0x010000001E37D75018E2988D7CA6066CA6F7C73BD2033028D17F0074     宗

C# 

加密
        public string EncryptCombined(string value, string passPhrase)
        {
          
            var keyBytes = Encoding.Unicode.GetBytes(passPhrase);
            // Depending on whether you're working with NVARCHAR/VARCHAR on SQL Server, use Unicode/UTF encoding here
            var valueBytes = Encoding.Unicode.GetBytes(value);
            var payload = new List<byte>();
            payload.AddRange(BitConverter.GetBytes(0xbaadf00d));
            payload.AddRange(BitConverter.GetBytes((UInt16)0));
            payload.AddRange(BitConverter.GetBytes((UInt16)valueBytes.Length));
            payload.AddRange(valueBytes);
            var payloadBytes = payload.ToArray();

            HashAlgorithm hash = SHA1.Create();
            SymmetricAlgorithm encryption = TripleDES.Create();
            encryption.GenerateIV();
            encryption.Padding = PaddingMode.PKCS7;
            encryption.Mode = CipherMode.CBC;
            hash.TransformFinalBlock(keyBytes, 0, keyBytes.Length);
            encryption.Key = hash.Hash.Take(16).ToArray();

            byte[] encryptedPayload = encryption.CreateEncryptor().TransformFinalBlock(payloadBytes, 0, payloadBytes.Length);

            byte[] version = new byte[] { 1, 0, 0, 0 };

            var encryptedBytes = new List<byte>();
            encryptedBytes.AddRange(version);
            encryptedBytes.AddRange(encryption.IV);
            encryptedBytes.AddRange(encryptedPayload);

            //return BitConverter.ToString(encryptedBytes.ToArray());
            //return "0x"+string.Join("",
            //    encryptedBytes.ToArray().Select(c => String.Format("{0:X2}", Convert.ToInt32(c))));
            StringBuilder hex = new StringBuilder(encryptedBytes.ToArray().Length * 2);
            foreach (byte b in encryptedBytes.ToArray())
                hex.AppendFormat("{0:x2}", b);
            return "0x"+hex.ToString();
        }

解密

        private byte[] HexStringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }

        string DecryptCombined(string FromSql, string Password)
        {
            try
            {                
                // Encode password as UTF16-LE
                byte[] passwordBytes = Encoding.Unicode.GetBytes(Password);

                // Remove leading "0x"
                FromSql = FromSql.Substring(2);

                int version = BitConverter.ToInt32(HexStringToByteArray(FromSql.Substring(0, 8)), 0);
                byte[] encrypted = null;

                HashAlgorithm hashAlgo = null;
                SymmetricAlgorithm cryptoAlgo = null;
                int keySize = (version == 1 ? 16 : 32);

                if (version == 1)
                {
                    hashAlgo = SHA1.Create();
                    cryptoAlgo = TripleDES.Create();
                    cryptoAlgo.IV = HexStringToByteArray(FromSql.Substring(8, 16));
                    encrypted = HexStringToByteArray(FromSql.Substring(24));
                }
                else if (version == 2)
                {
                    hashAlgo = SHA256.Create();
                    cryptoAlgo = Aes.Create();
                    cryptoAlgo.IV = HexStringToByteArray(FromSql.Substring(8, 32));
                    encrypted = HexStringToByteArray(FromSql.Substring(40));
                }
                else
                {
                    //throw new Exception("Unsupported encryption");
                    return "";
                }

                cryptoAlgo.Padding = PaddingMode.PKCS7;
                cryptoAlgo.Mode = CipherMode.CBC;

                hashAlgo.TransformFinalBlock(passwordBytes, 0, passwordBytes.Length);
                cryptoAlgo.Key = hashAlgo.Hash.Take(keySize).ToArray();

                byte[] decrypted = cryptoAlgo.CreateDecryptor().TransformFinalBlock(encrypted, 0, encrypted.Length);
                int decryptLength = BitConverter.ToInt16(decrypted, 6);
                UInt32 magic = BitConverter.ToUInt32(decrypted, 0);
                if (magic != 0xbaadf00d)
                {
                    //throw new Exception("Decrypt failed");
                    return "";
                }

                byte[] decryptedData = decrypted.Skip(8).ToArray();
                bool isUtf16 = (Array.IndexOf(decryptedData, (byte)0) != -1);
                string decryptText = (isUtf16 ? Encoding.Unicode.GetString(decryptedData) : Encoding.Unicode.GetString(decryptedData));
                
                //Console.WriteLine("Result: {0}", decryptText);
                return decryptText;
            }
            catch(Exception ex)
            {
                return "";
            }
        }