出于加密目的,对象销毁是否可靠? [英] Is object destruction reliable for cryptographic purposes?

查看:89
本文介绍了出于加密目的,对象销毁是否可靠?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为此问题的后续文章,我正在想象一个用于存储敏感数据(如加密密钥)的类.为简化起见,假设不涉及继承.

As a follow-on to this question, I'm imagining a class which stores sensitive data, like cryptographic keys. To simplify things, assume there's no inheritance involved.

struct Credential {
  std::array<uint8_t, 32> secretStuff;
  ~Credential() { memset_s(secretStuff.data(), 32, 0, 32); }
}

我正在尝试确定是否可以保证运行此类型的对象的析构函数,或者我是否需要做一些花哨的事情喜欢使用分配器以确保擦除内存.我对抵御编译器优化的弹性很感兴趣,因此我正在寻找标准的章节,以确保无论如何我都会得到正确的行为.

I'm trying to determine if objects of this type are guaranteed to have their destructor run, or if I need to do something fancy like use an Allocator to ensure the memory is wiped. I'm interested in resiliency against compiler optimizations, so I'm looking for chapter-and-verse from the standards to assure me that I'm going to get the right behavior no matter what.

在前面的问题中,已经确定可以确保自动分配的存储和static存储中的对象运行其析构函数.我对static案例不感兴趣;就我而言,确保程序终止后先前使用的内存内容不会泄漏是操作系统的职责.对于程序员故意破坏事物的情况,我也不感兴趣...毕竟,没有什么可说的是他们不能只复制数据.

In previous questions, it's been established that objects in automatically-allocated and static storage are guaranteed to have their destructors run. I'm not interested in the static case; as far as I'm concerned it's the OS's job to make sure that the contents of previously-used memory don't leak once the program is terminated. I'm also not interested in cases where the programmer is deliberately breaking things... after all, there's nothing to say they can't just copy the data out in the first place.

假设您是一名编译器作者,并且想在遵守标准的同时打破它.您有什么办法可以避免调用析构函数(程序终止除外)?也许一些奇怪的异常处理行为?如果不允许您这样做,为什么不这样做呢?

Imagine you were a compiler author and wanted to break this while complying with the standard. Is there anything you could do to avoid calling the destructor (excepting program termination)? Maybe some strange exception handling behavior? And if you wouldn't be allowed to, why not, specifically?

推荐答案

此处涉及两个问题.一种是可观察到的效果.允许析构函数具有可观察到的效果,并且当这样做时,这是很难保证的.析构函数可以将数据刷新到文件,如果析构函数未运行,该文件将丢失.析构函数可以释放由裸指针引用的对象,如果该析构函数未运行,则裸对象会泄漏该对象.析构函数与其他函数同等重要,它们的可见副作用无法神奇地消失.

There are two issues involved here. One is observable effects. Destructors are allowed to have observable effects and when they do, that is a hard guarantee. A destructor can flush data to a file that would be lost if the destructor didn't run. A destructor can free objects referenced by naked pointers that would leak if the destructor didn't run. Destructors are just as important as every other function and their visible side-effects cannot magically disappear.

但是,如果您担心无法观察到的影响,那么所有的赌注都将关闭.编译器可以证明对兼容程序没有明显影响的任何东西都可以被优化.这就是为什么我们要使用memset_s的原因,除非您仅使用函数定义可观察的所有效果,否则所有选项都将关闭.

However, if you're concerned about non-observable effects, all bets are off. Anything a compiler can prove has no observable effects to a compliant program can be optimized away. This is why we have memset_s and unless you only use functions that define all the effects you want to rely on as observable, all bets are off.

这篇关于出于加密目的,对象销毁是否可靠?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆