rsk*_*k82 3 php cryptography xor
我在这里尝试做的是创建一个函数,每次调用它时都会将相同的输入加密为完全不同的输出.这个函数的基础是xor,但是为了防止在字符串中容易发现重复模式.我根据时间和字符串的一部分添加了随机散列,以便在解密时进行自我验证.
我要求的是,如果我在这里犯了任何错误,可以向有经验的人透露隐藏的文字而不对字符串施加暴力.(我知道php有一个模块只是用于加密,但这是一个糟糕的勒芒版本,以防加密模块不可用.)第二:我不要求你重写这个功能或为我写一些东西,我要求的是我做错了一个简单的指导.我知道一个可能的安全漏洞是我默认使用salsa,这对于空字符串都是零,但优点是这是php中可用的最长哈希,其次,傻瓜会使用空密码来保护他们的数据?
function crapt($str,$pass,$hmac = false,$meth = 'salsa20') {
$hash = pack('H*',($hmac===false) ? hash($meth,$pass) : hash_hmac($meth,$pass,$hmac));
$str = gzdeflate($str,9);
$tmphash = pack('H*',sha1(sin(microtime(1))));
$str = $tmphash.((string)$str ^ (string)str_repeat($tmphash,strlen($str)/strlen($tmphash)+1));
$str .= pack('H*',sha1($str));
return (string)$str ^ (string)str_repeat($hash,strlen($str)/strlen($hash)+1);
}
function decrapt($str,$pass,$hmac = false,$meth = 'salsa20') {
$hash = pack('H*',($hmac===false) ? hash($meth,$pass) : hash_hmac($meth,$pass,$hmac));
$str = (string)$str ^ (string)str_repeat($hash,strlen($str)/strlen($hash)+1);
$check = substr($str,-20);
$str = substr($str,0,strlen($str)-20);
if(pack('H*',sha1($str))!==$check) return false;
$tmphash = substr($str,0,20);
$str = substr($str,20);
return gzinflate((string)$str ^ (string)str_repeat($tmphash,strlen($str)/strlen($tmphash)+1));
}
var_dump(decrapt(crapt('sometext','secretpassword'),'secretpassword'));
Run Code Online (Sandbox Code Playgroud)
您的算法以长度块运行strlen($hash)==strlen($tmphash).编辑:错了,但见下文.
在密文中,第一个这样的块等于($tmphash XOR $hash).以下各自等于(a_block_of_plaintext XOR $tmphash XOR $hash).
第一个密文块是数据的关键.只需重复密文的第一个块,然后得到明文即可.无需密码.
我不是PHP程序员,所以也许我错过了一些东西,但实际的攻击与此并没有太大的不同.
一般来说,只使用专业级加密模块.如果它们不可用,则您的应用程序不安全.
编辑:通过重读我注意到的问题,$hash并$tmphash有不同的长度.
$hash是512位,$tmphash是160位.然而,这并没有改变基本思想; 由于512和160的最小公倍数是2560,所以这些块每2560位同步一次.因此,您只能解密每个2560位块的前160位.
| 归档时间: |
|
| 查看次数: |
1277 次 |
| 最近记录: |