c# - 在 T-SQL 上解密 AES 128

标签 c# .net sql-server tsql encryption

我有一个当前使用 AES 128 的数据库。该数据库有大约 800 万条记录,客户想要的是解码密码并对其进行哈希处理,这样就无法解密密码。这是一个网络应用程序,数据存储在远程服务器上。我尝试使用网络应用程序进行转换,但它总是超时。由于这是 800 万,因此需要一段时间才能完成所有项目,所以我的下一个想法是让 SQL 进行解密和散列。我可以让它在接下来的几天内运行。

我遇到的问题是每一列都有带有唯一盐的加密密码。我找不到使用加密密码和盐来解密密码的功能。有功能吗?甚至第三方?有没有更好的方法来解决这个问题?

谢谢!

最佳答案

在 SQL Server 中执行此操作的最简单/唯一方法是在 C# 中编写 CLR 用户定义函数 (UDF)。见

了解更多详情。如果是我,我会添加一个新列来包含新密码哈希并定期运行更新语句来构建新密码哈希,如下所示:

update top 10000 dbo.users
set hashedPassword = DecryptAndHash( encryptedPassword )
where hashedPassword is null

DecryptAndHash() 是您的 CLR UDF。转换完成后,您应该可以随意删除旧列并推出更新以使用新的身份验证逻辑。

可能想在表上放置一个触发器,使哈希与加密密码保持同步,以防有人在这一切发生时更改密码。

FWIW,代码应该不会比

复杂多少
using System;
using Microsoft.SqlServer.Server;

namespace Sandbox
{
    public static class EncryptionFunctions
    {

        /// <summary>
        /// Encrypts a string
        /// </summary>
        /// <param name="plainText"></param>
        /// <returns>varbinary</returns>
        [SqlFunction]
        public static byte[] Encrypt( string plainText )
        {
            byte[] cipherText ;
            using ( EncryptionEngine cipher = EncryptionEngine.GetInstance() )
            {
                cipherText = cipher.Encrypt( plainText ) ;
            }
            return cipherText ;
        }

        /// <summary>
        /// Decrypts a previously encrypted varbinary
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns>string</returns>
        [SqlFunction]
        public static string Decrypt( byte[] cipherText )
        {
            string plainText ;
            using ( EncryptionEngine cipher = EncryptionEngine.GetInstance() )
            {
                plainText = cipher.Decrypt( cipherText ) ;
            }
            return plainText ;
        }

        /// <summary>
        /// Compute the secure hash of a [plaintext] string
        /// </summary>
        /// <param name="plainText"></param>
        /// <returns> varbinary </returns>
        [SqlFunction]
        public static byte[] SecureHash( string plainText )
        {
            byte[] hash ;
            using ( EncryptionEngine cipher = EncryptionEngine.GetInstance() )
            {
                hash = cipher.ComputeSecureHash( plainText ) ;
            }
            return hash ;
        }

        /// <summary>
        /// Convenience wrapper method to take a previously encrypted string, decrypt it and compute its secure hash
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns>varbinary</returns>
        [SqlFunction]
        public static byte[] DecryptAndHash( byte[] cipherText )
        {
            byte[] hash ;
            using ( EncryptionEngine cipher = EncryptionEngine.GetInstance() )
            {
                hash = cipher.ComputeSecureHash( cipher.Decrypt( cipherText ) ) ;
            }
            return hash ;
        }

        /// <summary>
        /// The core encrypt/decrypt/hash engine
        /// </summary>
        private class EncryptionEngine : IDisposable
        {
            /// <summary>
            /// get an instance of this class
            /// </summary>
            /// <returns></returns>
            public static EncryptionEngine GetInstance()
            {
                return new EncryptionEngine() ;
            }

            #region IDisposable Members

            /// <summary>
            /// Dispose of any unmanaged resources
            /// </summary>
            public void Dispose()
            {
                throw new NotImplementedException();
            }

            #endregion

            /// <summary>
            /// Encrypt a plaintext string
            /// </summary>
            /// <param name="plainText"></param>
            /// <returns></returns>
            internal byte[] Encrypt( string plainText )
            {
                throw new NotImplementedException();
            }

            /// <summary>
            /// Decrypt an encrypted string
            /// </summary>
            /// <param name="cipherText"></param>
            /// <returns></returns>
            internal string Decrypt( byte[] cipherText )
            {
                throw new NotImplementedException();
            }

            /// <summary>
            /// Compute the secure hash of a string
            /// </summary>
            /// <param name="plainText"></param>
            /// <returns></returns>
            internal byte[] ComputeSecureHash( string plainText )
            {
                throw new NotImplementedException();
            }

        }

    }
}

EncryptionEngine 的内部实现留给读者作为练习。

关于c# - 在 T-SQL 上解密 AES 128,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5822260/

相关文章:

c# - 使用外部 SQL Server 2008 R2 更新 linq 中的语句

c# - 同一 View 中的普通模型和 IEnumerable 模型

c# - 将 C# 列表转换为 JSON 特定格式

c# - MVC1000 使用 IHtmlHelper.Partial 可能会导致应用程序死锁。考虑使用 <partial> 标签助手或 IHtmlHelper.PartialAsync

.net - 无法创建迁移。错误 MSB1009 : Project file does not exist

sql-server - 将大量数据粘贴到 Excel

c# - 如何在 C# 中通过代码设置 ServiceHostingEnvironmentSection.AspNetCompatibilityEnabled

c# - 无法关闭 MySQL 数据库连接

c# - 在没有 SQL View 的情况下,将数据反规范化为代码优先 Entity Framework 实体

sql-server - 左连接和内连接的性能差异