这个基于xor的加密功能安全吗?

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)

Nic*_*son 13

你自己发明的任何密码无疑都会有漏洞 - 如果我们这些Stack Overflow上的人无法检测到它,那并不意味着别人不会.密码学的第一条规则不是发明自己的密码:使用现有密码,并在可能的情况下使用众所周知且经过测试的实现.如果您绝对不能使用标准库,请实现现有密码,例如TEA - 或者更好,使用您选择的语言查找现有实现.


Gia*_*ale 7

您的算法以长度块运行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位.