<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Cristiano WebLog : SQL Server 2005</title><link>http://blogs.msdn.com/crisag/archive/tags/SQL+Server+2005/default.aspx</link><description>Tags: SQL Server 2005</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Using SQL Server 2005 CLR SPs to create Commerce Server 2007 User Profile Password Hashes</title><link>http://blogs.msdn.com/crisag/archive/2006/09/19/Using-SQL-Server-2005-CLR-SPs-to-create-Commerce-Server-2007-User-Profile-Password-Hashes.aspx</link><pubDate>Tue, 19 Sep 2006 17:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:762094</guid><dc:creator>crisag</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/crisag/comments/762094.aspx</comments><wfw:commentRss>http://blogs.msdn.com/crisag/commentrss.aspx?PostID=762094</wfw:commentRss><wfw:comment>http://blogs.msdn.com/crisag/rsscomments.aspx?PostID=762094</wfw:comment><description>&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Do you&amp;nbsp;need convert passwords stored originally using plain-text on databases to the one-way hash format used by the new version of the Commerce Server?&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Don’t think that Commerce Server never used hashes to store passwords. It has always implemented this kind of functionality. Sometimes developers simple opt do not use hashes and decide store passwords using plain-text… :( &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;On the previous versions of CS the algorithm used was MD5 but one of the new features implemented by the last version was the use of the SHA256 hash algorithm to store passwords and other one-way pieces of information.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;Would you like a SQL 2005 stored procedure to generate CS2007 compatible hashes using the plain-text stored sources?&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;It can be used only passing the plain-text password as a parameter; the result of the procedure is a Commerce Server 2007 compatible hash already formatted using little-endian.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;The procedure was developed using the new .Net compatible stored procedures implemented by the last version of Microsoft SQL Server. &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;The code:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;using System;&lt;BR&gt;using System.Data;&lt;BR&gt;using System.Data.SqlClient;&lt;BR&gt;using System.Data.SqlTypes;&lt;BR&gt;using Microsoft.SqlServer.Server;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;using System.Text;&lt;BR&gt;using System.Security.Cryptography;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;public partial class StoredProcedures&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Microsoft.SqlServer.Server.SqlProcedure]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void Hash( string inputPassword )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SqlContext.Pipe.Send(ComputeHash(inputPassword));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception e)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SqlContext.Pipe.Send("Um erro ocorreu: " + e.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static string ComputeHash( string inputPassword )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] saltBytes;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Random random = new Random(); // gera um numero randomico para o tamanho da semente.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int saltSize = random.Next(4, 4);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; saltBytes = new byte[saltSize]; // aloca o vetor que armazenará o salt&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // inicializa o gerador de números randomicos&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rng.GetNonZeroBytes(saltBytes); // preenche a semente&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Text.UnicodeEncoding encode = new System.Text.UnicodeEncoding();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // encoding format is little endian&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] dataBuffer = new byte[encode.GetByteCount(inputPassword) + 4]; // get number of bytes and create buffer&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // copia os bytes to texto para o vetor&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; saltBytes.CopyTo(dataBuffer, 0);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] inputPasswordBytes = encode.GetBytes(inputPassword);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // copia os bytes da senha após os 4 destinados a semente&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inputPasswordBytes.CopyTo(dataBuffer, 4);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HashAlgorithm SHA256 = new SHA256Managed();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] hash = SHA256.ComputeHash(dataBuffer);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Text.StringBuilder sb = new System.Text.StringBuilder();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (byte outputByte in saltBytes) sb.Append(outputByte.ToString("x2").ToUpper());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (byte outputByte in hash) sb.Append(outputByte.ToString("x2").ToUpper());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return sb.ToString();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;} &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;You can use the Deploy command of the Microsoft Visual Studio 2005 to install the procedure on your SQL Server 2005 or you can use the following procedure to have it working on your environment:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;1.&amp;nbsp;Make sure that CLR Integration is enabled on the SQL server.&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;EXEC sp_configure 'clr enabled', 1&lt;BR&gt;RECONFIGURE&lt;BR&gt;GO&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;2.&amp;nbsp;Compile the code to generate the HashProcedure.dll file.&lt;BR&gt;3.&amp;nbsp;Execute the following T-SQL code against the SQL Server to add the CLR stored procedure:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;CREATE ASSEMBLY HashProcedure &lt;BR&gt;FROM 'C:\Work\Projetos\HashProcedure\bin\Debug\HashProcedure.dll'&lt;BR&gt;WITH PERMISSION_SET = SAFE &lt;BR&gt;GO&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;4.&amp;nbsp;Execute the following T-SQL code against the SQL Server do create a SQL Server 2005 stored procedure that Consumes the CLR code:&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;CREATE PROC Hash&lt;BR&gt;@inputPassword NVARCHAR(4000)&lt;BR&gt;AS&lt;BR&gt;EXTERNAL NAME HashProcedure.StoredProcedures.Hash&lt;BR&gt;GO&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;[]’s.&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN deactivatedstyle="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-fareast-font-family: 'MS Mincho'; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"&gt;&lt;FONT face=Verdana size=3&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=762094" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/crisag/archive/tags/SQL+Server+2005/default.aspx">SQL Server 2005</category><category domain="http://blogs.msdn.com/crisag/archive/tags/Commerce+Server/default.aspx">Commerce Server</category></item></channel></rss>