<?php
/**
* Security_DSA
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/bsd-license.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @category Security
* @package Security
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @copyright (c) 2004 Daiji Hriata All Right Reserved.
*
* Author: Daiji Hriata (DSA verify logic in Auth_TypeKey)
* Author: ishinao <[email protected]> (repackage to Security_DSA)
* $Id$
*
* = how to use =
* if (Security_DSA::verify($message, $sig, $p, $q, $g, $pubKey)) {
* echo 'verify success';
* } else {
* echo 'verify failed';
* }
*/
class Security_DSA
{
/**
* DSA verify
*
* @param string $message message
* @param string $sig signature
* @param array $sigKeys key
* @return boolean if success
* @exception Exception if extension not exists
*/
public static function verify($message, $sig, $sigKeys)
{
if (extension_loaded('gmp')) {
return self::_verifyByGmp($message, $sig, $sigKeys);
} else if (extension_loaded('bcmath')) {
return self::_verifyByBcmath($message, $sig, $sigKeys);
} else {
throw new Exception('gmp or bcmath extension required');
}
} /**
* verify using gmp extendsions
*/
private static function _verifyByGmp($message, $sig, $sigKeys)
{
$p = $sigKeys['p'];
$q = $sigKeys['q'];
$g = $sigKeys['g'];
$pubKey = $sigKeys['pub_key']; list ($r_sig, $s_sig) = explode(":", $sig);
$r_sig = base64_decode($r_sig);
$s_sig = base64_decode($s_sig); $p = gmp_init($p);
$q = gmp_init($q);
$g = gmp_init($g);
$pubKey = gmp_init($pubKey); $s1 = self::_bindecGmp($r_sig);
$s2 = self::_bindecGmp($s_sig); $w = gmp_invert($s2, $q);
$hash_m = gmp_init('0x'.sha1($message)); $u1 = gmp_mod(gmp_mul($hash_m, $w), $q);
$u2 = gmp_mod(gmp_mul($s1, $w), $q); $v =
gmp_mod(
gmp_mod(
gmp_mul(
gmp_powm($g, $u1, $p),
gmp_powm($pubKey, $u2, $p)
),
$p),
$q
); return (gmp_cmp($v, $s1) == 0);
} /**
* binary decode using gmp extension
*/
private static function _bindecGmp($bin)
{
$dec = gmp_init(0);
for ($i = 0; $i < strlen($bin); $i ++) {
$dec = gmp_add(gmp_mul($dec, 256), ord($bin{$i}));
}
return $dec;
} /**
* verify using bcmath extension
*/
private static function _verifyByBcmath($message, $sig, $sigKeys)
{
$p = $sigKeys['p'];
$q = $sigKeys['q'];
$g = $sigKeys['g'];
$pubKey = $sigKeys['pub_key']; list ($r_sig, $s_sig) = explode(':', $sig); $r_sig = base64_decode($r_sig);
$s_sig = base64_decode($s_sig); $s1 = self::_bindecBcmath($r_sig);
$s2 = self::_bindecBcmath($s_sig); $w = self::_invertBcmath($s2, $q);
$hash_m = self::_hexdecBcmath(sha1($message)); $u1 = bcmod(bcmul($hash_m, $w), $q);
$u2 = bcmod(bcmul($s1, $w), $q); $v =
bcmod(
bcmod(
bcmul(
bcmod(
self::_powmodBcmath($g, $u1, $p),
$p
),
bcmod(
self::_powmodBcmath($pubKey, $u2, $p),
$p
)
),
$p
),
$q
); return (bccomp($v, $s1) == 0);
} /**
* hex decode using bcmath extension
*/
private static function _hexdecBcmath($hex)
{
$dec = '0';
for ($i = 0; $i < strlen($hex); $i += 4) {
$dec = bcadd(bcmul($dec, 65536), HexDec(substr($hex, $i, 4)));
}
return $dec;
} /**
* binary decode using bcmath extension
*/
private static function _bindecBcmath($bin)
{
$dec = '0';
for ($i = 0; $i < strlen($bin); $i ++) {
$dec = bcadd(bcmul($dec, 256), ord($bin{$i}));
}
return $dec;
} /**
* invert using bcmath extension
*/
private static function _invertBcmath($x, $y)
{
while (bccomp($x, 0) < 0) {
$x = bcadd($x, $y);
}
$r = self::_exgcdBcmath($x, $y);
if ($r[2] == 1) {
$a = $r[0];
while (bccomp($a, 0) < 0) {
$a = bcadd($a, $y);
}
return $a;
} else {
return false;
}
} /**
* exgcd using bcmath extension
*/
private static function _exgcdBcmath($x, $y)
{
$a0 = 1;
$a1 = 0;
$b0 = 0;
$b1 = 1;
$c = 0;
while ($y > 0) {
$q = bcdiv($x, $y, 0);
$r = bcmod($x, $y);
$x = $y;
$y = $r;
$a2 = bcsub($a0, bcmul($q, $a1));
$b2 = bcsub($b0, bcmul($q, $b1));
$a0 = $a1;
$a1 = $a2;
$b0 = $b1;
$b1 = $b2;
}
return array ($a0, $b0, $x);
} /**
* powmod using bcmath extension
*/
private static function _powmodBcmath($x, $y, $mod)
{
if (function_exists('bcpowmod')) {
return bcpowmod($x, $y, $mod);
} else {
if (bccomp($y, 1) == 0) {
return bcmod($x, $mod);
} else if (bcmod($y, 2) == 0) {
return bcmod(bcpow(self::_powmodBcmath($x, bcdiv($y, 2), $mod), 2), $mod);
} else {
return bcmod(bcmul($x, self::_powmodBcmath($x, bcsub($y, 1), $mod)), $mod);
}
}
}
}
/**
* Security_DSA
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/bsd-license.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @category Security
* @package Security
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @copyright (c) 2004 Daiji Hriata All Right Reserved.
*
* Author: Daiji Hriata (DSA verify logic in Auth_TypeKey)
* Author: ishinao <[email protected]> (repackage to Security_DSA)
* $Id$
*
* = how to use =
* if (Security_DSA::verify($message, $sig, $p, $q, $g, $pubKey)) {
* echo 'verify success';
* } else {
* echo 'verify failed';
* }
*/
class Security_DSA
{
/**
* DSA verify
*
* @param string $message message
* @param string $sig signature
* @param array $sigKeys key
* @return boolean if success
* @exception Exception if extension not exists
*/
public static function verify($message, $sig, $sigKeys)
{
if (extension_loaded('gmp')) {
return self::_verifyByGmp($message, $sig, $sigKeys);
} else if (extension_loaded('bcmath')) {
return self::_verifyByBcmath($message, $sig, $sigKeys);
} else {
throw new Exception('gmp or bcmath extension required');
}
} /**
* verify using gmp extendsions
*/
private static function _verifyByGmp($message, $sig, $sigKeys)
{
$p = $sigKeys['p'];
$q = $sigKeys['q'];
$g = $sigKeys['g'];
$pubKey = $sigKeys['pub_key']; list ($r_sig, $s_sig) = explode(":", $sig);
$r_sig = base64_decode($r_sig);
$s_sig = base64_decode($s_sig); $p = gmp_init($p);
$q = gmp_init($q);
$g = gmp_init($g);
$pubKey = gmp_init($pubKey); $s1 = self::_bindecGmp($r_sig);
$s2 = self::_bindecGmp($s_sig); $w = gmp_invert($s2, $q);
$hash_m = gmp_init('0x'.sha1($message)); $u1 = gmp_mod(gmp_mul($hash_m, $w), $q);
$u2 = gmp_mod(gmp_mul($s1, $w), $q); $v =
gmp_mod(
gmp_mod(
gmp_mul(
gmp_powm($g, $u1, $p),
gmp_powm($pubKey, $u2, $p)
),
$p),
$q
); return (gmp_cmp($v, $s1) == 0);
} /**
* binary decode using gmp extension
*/
private static function _bindecGmp($bin)
{
$dec = gmp_init(0);
for ($i = 0; $i < strlen($bin); $i ++) {
$dec = gmp_add(gmp_mul($dec, 256), ord($bin{$i}));
}
return $dec;
} /**
* verify using bcmath extension
*/
private static function _verifyByBcmath($message, $sig, $sigKeys)
{
$p = $sigKeys['p'];
$q = $sigKeys['q'];
$g = $sigKeys['g'];
$pubKey = $sigKeys['pub_key']; list ($r_sig, $s_sig) = explode(':', $sig); $r_sig = base64_decode($r_sig);
$s_sig = base64_decode($s_sig); $s1 = self::_bindecBcmath($r_sig);
$s2 = self::_bindecBcmath($s_sig); $w = self::_invertBcmath($s2, $q);
$hash_m = self::_hexdecBcmath(sha1($message)); $u1 = bcmod(bcmul($hash_m, $w), $q);
$u2 = bcmod(bcmul($s1, $w), $q); $v =
bcmod(
bcmod(
bcmul(
bcmod(
self::_powmodBcmath($g, $u1, $p),
$p
),
bcmod(
self::_powmodBcmath($pubKey, $u2, $p),
$p
)
),
$p
),
$q
); return (bccomp($v, $s1) == 0);
} /**
* hex decode using bcmath extension
*/
private static function _hexdecBcmath($hex)
{
$dec = '0';
for ($i = 0; $i < strlen($hex); $i += 4) {
$dec = bcadd(bcmul($dec, 65536), HexDec(substr($hex, $i, 4)));
}
return $dec;
} /**
* binary decode using bcmath extension
*/
private static function _bindecBcmath($bin)
{
$dec = '0';
for ($i = 0; $i < strlen($bin); $i ++) {
$dec = bcadd(bcmul($dec, 256), ord($bin{$i}));
}
return $dec;
} /**
* invert using bcmath extension
*/
private static function _invertBcmath($x, $y)
{
while (bccomp($x, 0) < 0) {
$x = bcadd($x, $y);
}
$r = self::_exgcdBcmath($x, $y);
if ($r[2] == 1) {
$a = $r[0];
while (bccomp($a, 0) < 0) {
$a = bcadd($a, $y);
}
return $a;
} else {
return false;
}
} /**
* exgcd using bcmath extension
*/
private static function _exgcdBcmath($x, $y)
{
$a0 = 1;
$a1 = 0;
$b0 = 0;
$b1 = 1;
$c = 0;
while ($y > 0) {
$q = bcdiv($x, $y, 0);
$r = bcmod($x, $y);
$x = $y;
$y = $r;
$a2 = bcsub($a0, bcmul($q, $a1));
$b2 = bcsub($b0, bcmul($q, $b1));
$a0 = $a1;
$a1 = $a2;
$b0 = $b1;
$b1 = $b2;
}
return array ($a0, $b0, $x);
} /**
* powmod using bcmath extension
*/
private static function _powmodBcmath($x, $y, $mod)
{
if (function_exists('bcpowmod')) {
return bcpowmod($x, $y, $mod);
} else {
if (bccomp($y, 1) == 0) {
return bcmod($x, $mod);
} else if (bcmod($y, 2) == 0) {
return bcmod(bcpow(self::_powmodBcmath($x, bcdiv($y, 2), $mod), 2), $mod);
} else {
return bcmod(bcmul($x, self::_powmodBcmath($x, bcsub($y, 1), $mod)), $mod);
}
}
}
}
解决方案 »
- 建表的问题
- 一个SQL语句的问题
- 数字或值错误 : 字符到数值的转换错误;请问该如何解决?
- lampp集成环境查询数据出问题,数据量过大?
- 怎么扭曲图片?
- mysql-4.0.22-win 安装后在database 栏目中击点右键怎么没有创建数据库或表的项目.(即无法建数据库)
- 高手帮我写个域名转向页面!
- 在php文件相互调用工作时,为什么调用前的变量,被调用后就为空了??
- 怎么在提交的页面里得到上一页中数组text form的值。
- PHP将Mysql数据库中的表的一部分放到了html的表中,是以.php的形式保存的,怎么将这张表放到网页上呢
- 我想整一个转义的效果,但是表达不清楚,各位客官进来看看就知道了
- form
这个不全吧? DSA有加密和解密两个过程的。但是我没有看到对应的方法。
还有,how to 和 function 的变量个数也不一致。。是否可以提供更为详细一些的资料? 谢谢了。
国内的相关资料没有找到,外国的只有这个了
http://blog.csdn.net/SysTem128/archive/2008/04/08/2260387.aspx如果你硬要说DSA数字签名的话 那就是加密方式使用DSA 改变下类里面那个加密方法就可以了.
目前就是需要使用DSA来实现数字签名,一定要DSA的类。
所以,你提供的链接还是没能解决掉我的问题。
谢谢你提供的资料。。
用 Mcrypt Encryption Functions 配合上面那个签名机制就行了.
这是手册评论里的一个加密Cookie的,可以参考下.<?phpfunction encryptCookie($value){
if(!$value){return false;}
$key = 'The Line Secret Key';
$text = $value;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
return trim(base64_encode($crypttext)); //encode for cookie
}function decryptCookie($value){
if(!$value){return false;}
$key = 'The Line Secret Key';
$crypttext = base64_decode($value); //decode cookie
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $crypttext, MCRYPT_MODE_ECB, $iv);
return trim($decrypttext);
}?>
继续寻找php版本中
我接触到的数字签名机制都不会包括解密.
加解密是另行机制去完成的,不符属于签名机制.
签名意在于保护其所标记数据的原始性和完整性.我自己写了一个简单基于密匙的加解密类
http://blog.csdn.net/SysTem128/archive/2008/04/17/2301108.aspx
不是高端加密就够用 可以自己再扩展.