<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Форум Рутокен &mdash; Ошибка в алгоритме проверки подписи в серверных скриптах на PHP]]></title>
	<link rel="self" href="https://forum.rutoken.ru/feed/atom/topic/2134/" />
	<updated>2014-10-06T12:02:07Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.rutoken.ru/topic/2134/</id>
		<entry>
			<title type="html"><![CDATA[Re: Ошибка в алгоритме проверки подписи в серверных скриптах на PHP]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/7631/#p7631" />
			<content type="html"><![CDATA[<p>Добрый день!<br />Спасибо Вам огромное за проведённый аудит.<br />Специально для таких случаев мы выложили исходные коды этого проекта на гитхаб <br /><a href="https://github.com/AktivCo/rutokenweb_php">https://github.com/AktivCo/rutokenweb_php</a> <br />Если вы сделаете указанные вами изменения на гитхабе мы их примем и сделаем проект лучше.</p>]]></content>
			<author>
				<name><![CDATA[Кирилл Мещеряков]]></name>
				<uri>https://forum.rutoken.ru/user/6786/</uri>
			</author>
			<updated>2014-10-06T12:02:07Z</updated>
			<id>https://forum.rutoken.ru/post/7631/#p7631</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Ошибка в алгоритме проверки подписи в серверных скриптах на PHP]]></title>
			<link rel="alternate" href="https://forum.rutoken.ru/post/7625/#p7625" />
			<content type="html"><![CDATA[<p>Ошибка в алгоритме проверки подписи в серверных скриптах примера на PHP<br /><a href="https://download.rutoken.ru/Rutoken_Web/serverside/source_RTW_PHP.zip">https://download.rutoken.ru/Rutoken_Web … TW_PHP.zip</a></p><p>Немного теории:<br />Пусть P = (x,y), тогда обратной к точек P является точка -P = (x, -y). Сумма P + (-P) = бесконченость.<br />Сумма точек P = (x1,y1) и Q = (x2,y2), где P != -Q, вычисляется по формулам:<br />x3 = L^2 - x1 - x2<br />y3 = L * (x1 - x3) - y1<br />L = (y2 - y1) / (x2 - x1), если P != Q<br />L = (3 * x1^2 + a) / (2 * y1), если P == Q</p><p>Переходим к коду<br />файл crypto\classes\Point.php<br />функция add</p><p>Разберём следующий код:<br />if (gmp_Utils::gmp_mod2(gmp_cmp($p1-&gt;x, $p2-&gt;x), $p1-&gt;curve-&gt;getPrime()) == 0) {<br />&nbsp; &nbsp; if (gmp_Utils::gmp_mod2(gmp_add($p1-&gt;y, $p2-&gt;y), $p1-&gt;curve-&gt;getPrime()) == 0) {<br />&nbsp; &nbsp; &nbsp; &nbsp; return self::$infinity;<br />&nbsp; &nbsp; } else {<br />&nbsp; &nbsp; &nbsp; &nbsp; return self::double($p1);<br />&nbsp; &nbsp; }<br />}</p><p>1.<br />Первая строка<br />if (gmp_Utils::gmp_mod2(gmp_cmp($p1-&gt;x, $p2-&gt;x), $p1-&gt;curve-&gt;getPrime()) == 0) {</p><p>1.1<br />Нам нужно проверить, что x1 == x2<br />gmp_cmp вернет 0, если x1 == x2. Положительное число, если x1 &gt; x2, и отрицательное, если x1 &lt; x2.<br />Результат сравнения (знаковое целое) передаётся в функцию gmp_Utils::gmp_mod2, там происходит деление.</p><p>Хотя этот код работает, но корректее будет использовать gmp_sub</p><p>1.2<br />Функция gmp_Utils::gmp_mod2 вернет строку с числом и далее она сравнивается с целочисленным нулем.<br />Да, в PHP делается приведение типов, но корректнее будет использовать gmp_cmp для сравнения.</p><p>2.<br />Следующая строка<br />if (gmp_Utils::gmp_mod2(gmp_add($p1-&gt;y, $p2-&gt;y), $p1-&gt;curve-&gt;getPrime()) == 0) {<br />Аналогично, для сравнения нужно использовать gmp_cmp</p><p>3.<br />Собственно, главная ошибка.<br />В коде проверется случай что y1 == -y2.<br />Но не проверяется случай y1 == y2 (то есть случай, когда P = Q)<br />Нужно добавить проверку </p><p>else if (gmp_cmp(gmp_Utils::gmp_mod2(gmp_sub($p1-&gt;y, $p2-&gt;y), $p1-&gt;curve-&gt;getPrime()), &#039;0&#039;) === 0)</p><p>Таким образом, код должен выглядеть так:<br />if (gmp_cmp(gmp_Utils::gmp_mod2(gmp_sub($p1-&gt;x, $p2-&gt;x), $p1-&gt;curve-&gt;getPrime()), &#039;0&#039;) === 0)<br />{<br />&nbsp; &nbsp; if (gmp_cmp(gmp_Utils::gmp_mod2(gmp_add($p1-&gt;y, $p2-&gt;y), $p1-&gt;curve-&gt;getPrime()), &#039;0&#039;) === 0)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; return self::$infinity;<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; else if (gmp_cmp(gmp_Utils::gmp_mod2(gmp_sub($p1-&gt;y, $p2-&gt;y), $p1-&gt;curve-&gt;getPrime()), &#039;0&#039;) === 0)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; return self::double($p1);<br />&nbsp; &nbsp; }<br />}</p>]]></content>
			<author>
				<name><![CDATA[Андрей Филиппов]]></name>
				<uri>https://forum.rutoken.ru/user/9563/</uri>
			</author>
			<updated>2014-10-06T07:21:25Z</updated>
			<id>https://forum.rutoken.ru/post/7625/#p7625</id>
		</entry>
</feed>
