避免/检测导出文件的操作

use*_*407 5 c++ security hash qt

我正在使用C ++ Qt应用程序。为了在应用程序或所连接的设备出现故障时为用户提供帮助,该程序会导出所有内部设置,并将它们存储在一个普通文件中(此刻为csv)。然后将该文件发送给公司(例如,每封邮件)。

为了避免对导出的设置进行不注意的操作(例如,导出后由用户手动操作),我需要某种机制来检测到这一点。

该方法应尽可能简单,因为这不是非常关键的信息,但仍然有效。

我能想到的只是散列或加密,但是我很确定已经有一个简单而优雅的解决方案。

Rei*_*ica 2

您可以使用多种摘要或加密签名方案之一。由于这必须离线工作,因此您的可执行文件必须包含一个秘密 - 无论是用于公钥加密的公钥,还是其他方式,但您永远无法以这种方式保护自己免受坚定的攻击者的攻击。一个不通过逆向工程就无法绕过的简单方案就足够了;如果有人可以进行逆向工程,那么你就完蛋了。

最简单的方案是对附加(或前置)私有秘密的文件内容进行哈希处理,并将哈希值附加到文件末尾。在接收端,您跳过哈希,添加秘密,重新哈希并进行比较。

如果检查工具应该是独立的且易于使用,则有两种选择:

  1. 构建要静态链接的 Qt,并静态链接到 C++ 运行时。然后使用该 Qt 版本构建该工具:它将非常小,远低于 1MB,并且没有依赖项。

  2. 将验证器作为单个 html 文件提供,并让它使用JavaScript File API。用户在 Web 浏览器中打开 html 文件,将文件拖放到放置区域,然后获得即时响应。如今,它可以在任何常见浏览器上运行,即 Edge、Chrome、Safari、Firefox、Konqueror...

在 Qt 中执行此操作的一种简单方法是将内容附加到内容的 SHA-256 的十六进制表示形式,并附加一个秘密:

static const kHexSealSize = 2+64; // hex SHA-256
static QByteArray kSecret { "Things taste bad without salt." };

QByteArray sealHash(const QByteArray & data, int size = -1) {
  if (size < 0) size = data.size();
  QCryptographicHash hash(QCryptographicHash::Sha256);
  hash.addData(data.constData(), size);
  hash.addData(kSecret);
  auto seal = QByteArray("\r\n") + hash.result().toHex();
  Q_ASSERT(hex.size() == kHexSealSize);
  return seal;
}

QByteArray seal(const QByteArray & data) {
  return data + sealHash(data);
}

/// Returns whether a seal is valid
bool checkSeal(const QByteArray & data) {
  if (data.size() < kHexSealSize) return false;
  auto hexSrc = data.right(kHexSealSize);
  auto hexCmp = sealHash(data, data.size() - kHexSealSize);
  return hexSrc == hexCmp;
}
Run Code Online (Sandbox Code Playgroud)