来自维基百科
在密码学中,定时攻击是一种侧信道攻击,攻击者通过分析执行加密算法所花费的时间来试图破坏密码系统.
实际上,为了防止定时攻击,我使用了以下从这个答案中获取的函数:
function timingSafeCompare($safe, $user) {
// Prevent issues if string length is 0
$safe .= chr(0);
$user .= chr(0);
$safeLen = strlen($safe);
$userLen = strlen($user);
// Set the result to the difference between the lengths
$result = $safeLen - $userLen;
// Note that we ALWAYS iterate over the user-supplied length
// This is to prevent leaking length information
for ($i = 0; $i < $userLen; $i++) {
// Using % here is a trick to …
Run Code Online (Sandbox Code Playgroud) PHP 5.6引入了hash_equals()
用于安全比较密码哈希和防止定时攻击的功能.它的签名是:
bool hash_equals(string $known_string, string $user_string)
Run Code Online (Sandbox Code Playgroud)
如文档中所述,$known_string
并且$user_string
必须具有相同长度的函数才能有效防止定时攻击(否则,false
立即返回,泄漏已知字符串的长度).
此外,文档说:
提供用户提供的字符串作为第二个参数而不是第一个参数非常重要.
我认为函数在其参数中不是对称的,这似乎不直观.
问题是:
这是函数源代码的摘录:
PHP_FUNCTION(hash_equals)
{
/* ... */
if (Z_STRLEN_P(known_zval) != Z_STRLEN_P(user_zval)) {
RETURN_FALSE;
}
/* ... */
/* This is security sensitive code. Do not optimize this for speed. */
for (j = 0; j < Z_STRLEN_P(known_zval); j++) {
result |= known_str[j] ^ user_str[j];
}
RETURN_BOOL(0 == result);
}
Run Code Online (Sandbox Code Playgroud)
至于我,这两个论点的实现是完全对称的.可能产生任何影响的唯一操作是XOR运算符.
XOR运算符是否可能在非常量时间内执行,具体取决于参数值?可能它的执行时间取决于参数的顺序(例如,如果第一个参数为零)?
或者,PHP的文档中的这个注释是对未来版本中实现更改的"保留"吗?
PHP_FUNCTION(hash_compare) …
Run Code Online (Sandbox Code Playgroud) 我试图在PHP中产生一个计时攻击使用PHP 7.1与以下脚本
<?php
$find = "hello";
$length = array_combine(range(1, 10), array_fill(1, 10, 0));
for ($i = 0; $i < 1000000; $i++) {
for ($j = 1; $j <= 10; $j++) {
$testValue = str_repeat('a', $j);
$start = microtime(true);
if ($find === $testValue) {
//do Nothing
}
$end = microtime(true);
$length[$j] += $end - $start;
}
}
arsort($length);
$length = key($length);
var_dump($length . " found");
$found = '';
$alphabet = array_combine(range('a', 'z'), array_fill(1, 26, 0));
for ($len = 0; $len < …
Run Code Online (Sandbox Code Playgroud) 我有两个问题,我不明白.请帮我看看.谢谢.
Java中的MessageDigest.isEqual函数有什么用?
解释为什么在Java SE 6 Update 17之前的某些版本中,它容易受到定时攻击.
今天我醒来并想是否有可能预测Strings只分析每次比较之间的时间.
我创建了一个基本的课程(我知道这不是最好的算法,但它对我有用)来尝试证明这一点,答案是肯定的.
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class Test {
public static final int iters = 1000000;
public static final String SECRET_WORD = "85742";
public static final char[] LETTERS = new char[] { '1', '2', '3', '4', '5',
'6', '7', '8', '9', '0' };
public static void main(String[] args) {
int length = calculateLength();
System.out.println("Secret word is " + SECRET_WORD
+ " with a real length of " + SECRET_WORD.length()
+ " and a calculate Length …
Run Code Online (Sandbox Code Playgroud) 这是一个边缘话题。因为我想了解编程、CPU 缓存、读取 CPU 缓存行等,所以我把它贴在这里。
我在 C/C++ 中实现了 AES 算法。由于在没有硬件支持的情况下执行 GF(2 8 ) 乘法在计算上是昂贵的,我已经优化为使用 AES S-box 的查找表。但不幸的是,基于查找表的实现容易受到缓存定时攻击。因此,由于对 CPU 缓存非常天真,我开始学习它的工作原理,以及如何在不增加任何计算成本的情况下规避这种攻击。
我意识到实际上有 AES NI 指令和 Bit Slice AES 实现,但它们远远超出了我目前的理解。
我从 crypto.SE 了解到,最简单的方法是在查找之前读取所有缓存行或读取整个表。(这也影响了我的表现)但是我不知道如何在软件中实现它,或者它背后的复杂概念。
在OpenSSLaes-x86core.c
的C 实现参考指南中—— 作者实现了一个功能:
static void prefetch256(const void *table)
{
volatile unsigned long *t=(void *)table,ret;
unsigned long sum;
int i;
/* 32 is common least cache-line size */
for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0])) sum ^= t[i];
ret = sum;
}
Run Code Online (Sandbox Code Playgroud)
for
循环i
中增加8 …
一个简单的实现memcmp()
是这样的(来自这个答案):
int memcmp_test(const char *cs_in, const char *ct_in, size_t n)
{
size_t i;
const unsigned char * cs = (const unsigned char*) cs_in;
const unsigned char * ct = (const unsigned char*) ct_in;
for (i = 0; i < n; i++, cs++, ct++)
{
if (*cs < *ct)
{
return -1;
}
else if (*cs > *ct)
{
return 1;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
一旦找到第一个不匹配字节,块遍历就会停止。这对于加密应用程序来说可能没有好处,因为它使得执行时间依赖于块内容,并且这可能允许定时攻击。所以 OpenSSL 使用这个(取自这里):
int CRYPTO_memcmp(const void *in_a, const void …
Run Code Online (Sandbox Code Playgroud)