用C ++遮盖敏感字符串的技术 [英] Techniques for obscuring sensitive strings in C++

查看:90
本文介绍了用C ++遮盖敏感字符串的技术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在C ++应用程序中存储敏感信息(我想保持私有的对称加密密钥).简单的方法是这样做:

  std :: string myKey =您不会猜到的mysupersupersecretpassword"; 

但是,通过 strings 进程(或从二进制应用程序中提取字符串的任何其他程序)运行该应用程序将显示上面的字符串.

应该使用什么技术来掩盖此类敏感数据?

好的,你们中几乎所有人都说过您的可执行文件可以进行反向工程" -当然!这是我的宠儿,所以在这里我要大声疾呼:

为什么本网站上所有与安全相关的问题中有99%(好的,所以我可能会夸张地说)用没有办法创建完美安全的程序"的答案来回答.-这不是有用的答案!安全性是介于完美可用性和一端没有安全性,而另一端是完美安全性却没有可用性之间的滑动标度.

重点是,您可以根据要执行的操作以及软件运行的环境来选择滑动比例尺上的位置.我不是为军事安装编写应用程序,而是为家用PC编写应用程序.我需要使用已知的加密密钥在不受信任的网络上加密数据.在这些情况下,通过模糊来保证安全"指的是安全性.可能已经足够好了!当然,有足够时间,精力和技能的人可以对二进制文件进行反向工程并找到密码,但是您猜怎么着?我不在乎:

实施一流的安全系统所花的时间要比由于破解版本而导致的销售损失要昂贵得多(不是我实际上是在卖此产品,但您明白我的意思).这种蓝天让它以绝对最佳的方式做到这一点".至少可以这样说,新程序员中编程的趋势是愚蠢的.

感谢您抽出宝贵的时间来回答这个问题-他们最有帮助.不幸的是,我只能接受一个答案,但是我对所有有用的答案都投票赞成.

解决方案

基本上,任何有权访问您的程序并使用调试器 的人都会在如果他们愿意的话,申请.

但是,如果您只想确保在二进制文件上运行 strings 时密钥不显示,则可以确保该密钥不在可打印范围内./p>

使用XOR遮盖密钥

例如,您可以使用XOR将密钥分成两个字节数组:

  key = key1 XOR key2 

如果您创建的key1与 key 的字节长度相同,则可以使用(完全)随机字节值,然后计算 key2 :

  key1 [n] = crypto_grade_random_number(0..255)key2 [n] = key [n] XOR key1 [n] 

您可以在构建环境中执行此操作,然后仅将 key1 key2 存储在应用程序中.

保护您的二进制文件

另一种方法是使用一种工具来保护您的二进制文件.例如,有几种安全工具可以确保二进制文件被模糊处理并启动在其上运行的虚拟机.这使调试变得更加困难,并且这也是保护许多商业级安全应用程序(also,恶意软件)的常规方式.

主要工具之一是 Themida ,它在保护二进制文件方面做得非常出色.众所周知的程序(例如Spotify)经常使用它来防止逆向工程.它具有防止在OllyDbg和Ida Pro等程序中进行调试的功能.

还有更多的>保护工具您的二进制文件.
其中一些是免费的.

密码匹配

这里有人讨论了哈希密码+盐.

如果您需要存储密钥以使其与某种用户提交的密码相匹配,则应使用单向哈希函数,最好将用户名,密码和盐组合在一起.但是,这样做的问题是您的应用程序必须知道盐才能单向执行并比较生成的哈希值.因此,您仍然需要将盐存储在应用程序中的某个位置.但是,正如@Edward在下面的评论中指出的那样,这将有效地防止使用例如彩虹表的字典攻击.

最后,您可以结合使用以上所有技术.

I need to store sensitive information (a symmetric encryption key that I want to keep private) in my C++ application. The simple approach is to do this:

std::string myKey = "mysupersupersecretpasswordthatyouwillneverguess";

However, running the application through the strings process (or any other that extracts strings from a binary app) will reveal the above string.

What techniques should be used to obscure such sensitive data?

Edit:

OK, so pretty much all of you have said "your executable can be reverse engineered" - of course! This is a pet peeve of mine, so I'm going to rant a bit here:

Why is it that 99% (OK, so perhaps I exaggerate a little) of all security-related questions on this site are answered with a torrent of "there is no possible way to create a perfectly secure program" - that is not a helpful answer! Security is a sliding scale between perfect usability and no security at one end, and perfect security but no usability at the other.

The point is that you pick your position on that sliding scale depending on what you're trying to do and the environment in which your software will run. I'm not writing an app for a military installation, I'm writing an app for a home PC. I need to encrypt data across an untrusted network with a pre-known encryption key. In these cases, "security through obscurity" is probably good enough! Sure, someone with enough time, energy and skill could reverse-engineer the binary and find the password, but guess what? I don't care:

The time it takes me to implement a top-notch secure system is more expensive than the loss of sales due to the cracked versions (not that I'm actually selling this, but you get my point). This blue-sky "lets do it the absolute best way possible" trend in programming amongst new programmers is foolish to say the least.

Thank you for taking the time to answer this question - they were most helpful. Unfortunately I can only accept one answer, but I've up-voted all the useful answers.

解决方案

Basically, anyone with access to your program and a debugger can and will find the key in the application if they want to.

But, if you just want to make sure the key doesn't show up when running strings on your binary, you could for instance make sure that the key is not within the printable range.

Obscuring key with XOR

For instance, you could use XOR to split the key into two byte arrays:

key = key1 XOR key2

If you create key1 with the same byte-length as key you can use (completely) random byte values and then compute key2:

key1[n] = crypto_grade_random_number(0..255)
key2[n] = key[n] XOR key1[n]

You can do this in your build environment, and then only store key1and key2 in your application.

Protecting your binary

Another approach is to use a tool to protect your binary. For instance, there are several security tools that can make sure your binary is obfuscated and starts a virtual machine that it runs on. This makes it hard(er) to debug, and is also the convential way many commercial grade secure applications (also, alas, malware) is protected.

One of the premier tools is Themida, which does an awesome job of protecting your binaries. It is often used by well known programs, such as Spotify, to protect against reverse engineering. It has features to prevent debugging in programs such as OllyDbg and Ida Pro.

There is also a larger list, maybe somewhat outdated, of tools to protect your binary.
Some of them are free.

Password matching

Someone here discussed hashing password+salt.

If you need to store the key to match it against some kind of user submitted password, you should use a one-way hashing function, preferrably by combining username, password and a salt. The problem with this, though, is that your application has to know the salt to be able to do the one-way and compare the resulting hashes. So therefore you still need to store the salt somewhere in your application. But, as @Edward points out in the comments below, this will effectively protect against a dictionary attack using, e.g, rainbow tables.

Finally, you can use a combination of all the techniques above.

这篇关于用C ++遮盖敏感字符串的技术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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