<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Saiman says &#187; SQL</title>
	<atom:link href="http://saiman.thefreeart.com/category/%d0%ba%d0%be%d0%bc%d0%bf%d1%8e%d1%82%d1%80%d0%b8/sql/feed" rel="self" type="application/rss+xml" />
	<link>http://saiman.thefreeart.com</link>
	<description>личен блог на saiman</description>
	<lastBuildDate>Tue, 27 Sep 2011 16:10:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Премахване на поверителната информация от базата от данни</title>
		<link>http://saiman.thefreeart.com/kompyutri/sql/premahvane-na-poveritelnata-informa</link>
		<comments>http://saiman.thefreeart.com/kompyutri/sql/premahvane-na-poveritelnata-informa#comments</comments>
		<pubDate>Thu, 16 Oct 2008 09:45:31 +0000</pubDate>
		<dc:creator>saiman</dc:creator>
				<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://saiman.thefreeart.com/?p=27</guid>
		<description><![CDATA[Представете си, че сте собственик на голям онлайн магазин. За вас работят екип програмисти, които непрекъснато добавят нова и нова функционалност към вече съществуващата или пък поправят бъговете, който изникват непрестанно. И програмистите са хора, има бъгове &#8211; има работа, &#8230; <a href="http://saiman.thefreeart.com/kompyutri/sql/premahvane-na-poveritelnata-informa">Има още <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Представете си, че сте собственик на голям онлайн магазин. За вас работят екип програмисти, които непрекъснато добавят нова и нова функционалност към вече съществуващата или пък поправят бъговете, който изникват непрестанно. И програмистите са хора, има бъгове &#8211; има работа, няма бъгове &#8211; няма работа. Бизнеса Ви се развива и Вие имате много клиенти. Съответно и Вашата база от данни е пълна с информацията въведена от клиентите. Често това са трите имена, адрес, телефон. Понякога дори номер на лична карта или пък номер на кредитна карта, без значение &#8211; всяко едно от изброените може да се счита за поверителна информация. Във Ваш интерес е, като собственик на магазина, да пазите тази информация. Предполага се, че базата от данни на магазина е добре защитена и е много трудно да се достъпи отвън, ако не и невъзможно, в този случай хората които имат достъп до тази информация са програмистите, които работят за Вас. На тях им е необходим достъп до базата, за да видят какво точно се е случило докато проследяват някой от бъговете.<br />
Добра практика е преди да се предостави достъп до базата, да се премахне поверителната информация от нея. В общия случай &#8222;идеално&#8220; решение няма. Един от възможните варианти е, да заменим полетата с поверителна информация, с NULL стойности. Удобно е, защото става много бързо и много лесно, лошото е че по този начин нарушаваме целостта на базата. Представете си, че имаме две таблици свързани посредством полето номер на лична карта. Когато въведем NULL в това поле ще загубим връзката между таблиците.<br />
Друг вариант е да хешираме всички полета с поверителна информация, например с MD5. По този начин ще запазим релациите. Неприятностите идват, когато се опитаме да инсталираме локално базата от данни, за да я използваме докато разработваме проекта. Причината е, че хишираната вече информация няма да премине валидирането в сайта. Начини има още много, аз ще се опитам да опиша още една от възможностите за премахване на тази информация от базата. Идеята е отново да се използва MD5 хеширане, но в полето с поверителна информация да не се слага хеша ами така избрана от нас стойност, която да преминава през съответните правила за валидиране в сайта. Например:</p>
<p>Таблица clients с колони id, име и фамилия:</p>
<blockquote><p>
1   Иван    Иванов<br />
2   Петър   Христов<br />
3   Георги  Христов
</p></blockquote>
<p>Таблица clients (след премахване на поверителната информация):</p>
<blockquote><p>
1   First_Name_1    Last_Name_1<br />
2   First_Name_2    Last_Name_2<br />
3   First_Name_3    Last_Name_2
</p></blockquote>
<p>За целта използваме спомагателна таблица, в която ще съхраняваме всички хешове. Ето как би изглеждала една такава таблица:</p>
<blockquote><p>
CREATE TABLE db_hashes(<br />
    hash VARCHAR(50) NOT NULL,<br />
    prefix VARCHAR(250) NOT NULL,<br />
    counter BIGINT(11) DEFAULT NULL,</p>
<p>    PRIMARY KEY (hash)<br />
) ENGINE=InnoDB;
</p></blockquote>
<p>В полето hash, ще записваме съответният hash за името, полетата prefix и counter, заедно ще образуват новата стойност. Ето и една примерна функция, която може да се използва за &#8222;изчистване&#8220; на текстови полета от базата.</p>
<blockquote><p>
DELIMITER |<br />
DROP FUNCTION IF EXISTS sanitize_string |<br />
CREATE FUNCTION sanitize_string(<br />
    input_data VARCHAR(255),<br />
    input_prefix VARCHAR(255),<br />
    input_salt VARCHAR(50)<br />
)<br />
RETURNS VARCHAR(255)<br />
DETERMINISTIC<br />
BEGIN</p>
<p>    DECLARE result VARCHAR(255);<br />
    DECLARE result_prefix VARCHAR(255);<br />
    DECLARE result_counter BIGINT;</p>
<p>    &#8212; check for existing data, which has the same hash<br />
    SELECT prefix, counter INTO result_prefix, result_counter<br />
    FROM db_hashes<br />
    WHERE hash = MD5(CONCAT(input_data, input_salt));</p>
<p>    IF result_prefix IS NOT NULL THEN<br />
        IF result_counter IS NOT NULL THEN<br />
            SET result = CONCAT(result_prefix, result_counter);<br />
        ELSE<br />
            SET result = result_prefix;<br />
        END IF;</p>
<p>        RETURN result;<br />
    END IF;</p>
<p>    &#8212; get the last counter if exist and write the new row with<br />
    &#8212; the new combination of prefix and counter<br />
    SELECT MAX(counter), prefix INTO result_counter, result_prefix<br />
    FROM db_hashes<br />
    WHERE prefix = input_prefix<br />
    GROUP BY prefix;</p>
<p>    IF result_prefix IS NULL THEN<br />
        SET result_counter = 1;<br />
    ELSE<br />
        SET result_counter = result_counter + 1;<br />
    END IF;</p>
<p>    INSERT INTO db_hashes<br />
    VALUES(MD5(CONCAT(input_data, input_salt)), input_prefix, result_counter);</p>
<p>    RETURN CONCAT(input_prefix, result_counter);<br />
END|<br />
DELIMITER ;
</p></blockquote>
<p>Ето как би изглеждала една заявка за премахване на поверителната информация от таблицата clients:</p>
<blockquote><p>
UPDATE clients SET<br />
first_name = sanitize_string(first_name, &#8216;First_Name_&#8217;, &#8216;salt&#8217;),<br />
last_name = sanitize_string(last_name, &#8216;Last_Name_&#8217;, &#8216;salt&#8217;);
</p></blockquote>
<p>Лесно можем да напишем и други такива функции, например за модифициране на числа, дати и т.н. Не твърдя че това е единственото решение, нито че е най-оптималното или най-подходящото, бих се радвал ако някой сподели и други начини за премахване на поверителната информация.</p>
]]></content:encoded>
			<wfw:commentRss>http://saiman.thefreeart.com/kompyutri/sql/premahvane-na-poveritelnata-informa/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

