- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是一个边缘话题。由于我想了解编程、CPU 缓存、读取 CPU 缓存行等,因此我将其发布在这里。
我在 C/C++ 中实现了 AES 算法。由于在没有硬件支持的情况下执行 GF(28) 乘法在计算上是昂贵的,因此我已经优化为使用 AES S-box 的查找表。但不幸的是,基于查找表的实现容易受到 cache-timing attacks 的影响。 .因此,由于对 CPU 缓存非常天真,我开始学习它的工作原理,以及如何在不增加任何计算成本的情况下规避这种攻击。
我意识到实际上有 AES NI 指令和 Bit Slice AES 实现,但它们远远超出了我目前的理解。
我从 crypto.SE 了解到,最简单的方法是读取所有缓存行,
或者在我查找之前阅读整个表格。 (这也影响了我的表现)
但是我不知道如何在软件中实现它,或者它背后的复杂概念。
在 C implementation reference guide of OpenSSL - aes-x86core.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;
}
for
循环 i
增加 8
如果 sizeof(t[0])
是 4。因为 AES sbox 是 unsigned char
256 个元素的数组,当我们调用 prefetch256(sbox)
时,sbox 指针被转换为 unsigned long
指针,因此每个元素都使用 t[i]
取消引用是 4 个字节。但我不明白为什么我们跳过 32 个字节,而不是完全读取它(以防止缓存定时攻击)? sum ^= t[i]
和设置 ret = sum
? unsigned char tmp[256];
memcpy(tmp, sbox, 256); // memcpy reads the full sbox table quickly..
最佳答案
In the for loop i is incremented by 8 if sizeof(t[0]) is 4.
But I don't understand the reasons why we skip 32 bytes, and not read it fully (to protect against cache timing attacks)?
i
增加相当于 32
char
s(不管
sizeof(t[0])
恰好是什么),因为“32
char
s”(或 32 字节)是作者确定的他们关心的所有 CPU 的最小缓存行大小。请注意,您只需从缓存行的 1 个字节中读取即可确保将整个缓存行提取到缓存中。
What is the motivation behind sum ^= t[i] and setting ret = sum ?
volatile
. OpenSSL 作者正在做这两项(试图通过执行
sum ^= t[i]
和
ret sum
来欺骗编译器不进行优化;并且还使用
volatile
),可能是因为(历史上)很多旧编译器都有涉及
volatile
的错误.
Will this following simpler code help me:
prefetch256()
相同的问题,并且可能会更慢,因为您正在写入内存而不是仅读取)。
Are there other simpler solutions to protect my implementation from cache timing attacks?
byte = table[index]
”,您不希望攻击者知道有关
index
的任何信息),您可以读取所有前面的缓存行,然后读取您想要的字节,然后读取所有后面的缓存行(这样它总是看起来像整个表的顺序读取)并以固定的速率进行这些访问(没有“读取你想要的字节之前暂停”和“读取你想要的字节后暂停”) ,包括“没有由分支错误预测引起的暂停”)。如果你这样做;那么您可以对自己抵御缓存时序攻击的能力有极高的信心(直到保证您的代码不受所有可能的缓存时序攻击的影响)。
uint16_t fetch_byte_from_table(int index) {
size_t table_entries = sizeof(table)/sizeof(table[0]);
uint8_t dummy = 0;
uint8_t data = 0;
for(i = 0; i < table_entries; i++) {
if(i == index) {
data ^= table[i];
} else {
dummy ^= table[i];
}
}
return ((uint16_t)dummy << 8) | data; // Caller can ignore the higher 8 bits
}
当然,您可以使用一些技巧来尝试隐藏或避免分支(例如
data ^= table[i] * (i == index); dummy = data ^= table[i] * (i != index);
),但它们取决于编译器和 objective-c PU。
关于c - 这个 prefetch256() 函数是否提供任何针对 AES 缓存定时攻击的保护?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61699873/
我只想使用这 3 种模式从 openSSL 测试 AES: key 长度为 128,192 和 256,但我的解密文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如说 1024
最近我终于(在 stackoverflow 的用户@WhozCraig 的帮助下)开始在 CBC 模式下使用 AES。现在,我想做完全相同的事情,但使用 AES IGE。我查看了 openssl-1.
网络设备已经配置了 snmpv3 用户,使用 AES192 作为隐私协议(protocol)。但是当执行以下命令时 snmpwalk -v3 -l authPriv -u user -a SHA -A
我在 c# 中使用 AES 算法进行加密和解密。我使用 AesCryptoServiceProvider 类进行加密和解密。 这是我在代码中的设置 AesCryptoServiceProvider r
我正在尝试使用具有不同 key 大小的 openssl 的 AES_decrypt 函数来解密密文。我能够成功解密 key 大小 = 128 的消息。这是我的代码 mydecrypt.c #inclu
如何在 AES-128、AES-192 和 AES-256 之间切换。我目前的实现仅使用 AES-128 Cipher cipher = Cipher.getInstance("AES/CBC/NoP
我的问题是我想在一个线图上叠加一个散点图,这两个图的颜色随着一个变量而变化。我只想保留一种颜色的图例。如果我使用 scale_colour_discrete(guide = "none") 它们都将消
我想用 C# 编写一个可以打开 KeePass 的程序1.x kdb 文件。我下载了源代码并尝试移植密码数据库读取功能。数据库内容已加密。加密 key 通过以下方式获得: 用户输入密码; 计算密码的
我只想将ruby代码迁移到Java 这是我的 ruby 代码 require 'openssl' require 'base64' key = '7c54367a45b37a192abc2cd7f45
我正在使用 AES 的 PyCrypto 实现,并且我正在尝试使用 24 字节 key 加密一些文本(24 字节)。 aes_ecb = AES.new('\x00'*24, AES.MODE_ECB
有人比较这些加密算法的优缺点吗? 最佳答案 使用 AES。 更多详细信息: DES 是七十年代的旧“数据加密标准”。它的 key 大小对于适当的安全性而言太短(56 个有效位;这可以被暴力破解,如 m
我在 iOS 中加密一个 NSString,编码和解码都很好: NSString *stringtoEncrypt = @"This string is to be encrypted"; NSStr
我正在尝试使用 nVidia CUDA 在 CTR 模式下实现 AES-256。我已经成功地为 key 扩展编写了 CPU 代码,现在我需要实现实际的 AES-256 算法。根据维基百科,我见过一些代
我正在 Contiki OS 中研究 AES 安全性。我有 AES 库,它支持两种类型的加密/解密: 即时 固定键 在即时中,当我使用 key 加密数据时,会生成新 key 和加密数据。这个新生成的
关于 AES 有很多问题,但我有以下问题。我目前正在使用以下 AES 实现来加密数据 byte [] PRFkey = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
有没有人一起比较这些加密算法的优缺点? 最佳答案 使用 AES。 更多细节: DES 是七十年代的旧“数据加密标准”。它的 key 大小对于适当的安全性来说太短了(56 位有效位;这可以被强制执行,正
我的团队需要开发一种解决方案,以在用 Java 编写的 Android 应用程序的上下文中加密二进制数据(存储为 byte[])。加密后的数据将通过多种方式传输和存储,在此过程中不排除出现数据损坏的情
我在客户端使用 CryptoJS AES 算法加密文本,我在服务器端用 java 解密它,但出现异常。 JS代码: var encrypted = CryptoJS.AES.encrypt("Mess
我之所以问这个问题,是因为 2 天来我已经阅读了很多关于加密 AES 加密的帖子,就在我以为我明白了的时候,我意识到我根本没有明白。 这篇文章是最接近我的问题的,我有完全相同的问题但没有得到解答: C
我想知道 AES 加密后的数据大小,这样我就可以避免缓冲我的 AES 后数据(在磁盘或内存上)主要是为了知道大小。 我使用 128 位 AES 和 javax.crypto.Cipher 和 java
我是一名优秀的程序员,十分优秀!