将 openssl 组合为控制台和库的问题

发布于 2024-10-14 10:52:28 字数 1755 浏览 6 评论 0原文

我想隐藏在 C/C++ 程序中用作字符串的文本信息(在我的例子中为 GLSL 着色器),因为它们可以在二进制文件中直接读取。因此,我考虑在编译/构建时加密文件并在运行时解密数据以继续重建着色器。

然而,我在让控制台上的 openssl 与 C 程序中的库 (evp) 一起工作时遇到了一些麻烦。我必须承认我绝不是密码学方面的专家,但现在必须进入这个主题......

这是我已经尝试过的:

// on the console:
openssl enc -aes-256-cbc -salt -in shader.frag -out shader.frag.enc

// ...

// in the program:

//// read enc file ////     
int lengthIN;
char * buffer_encIN;

ifstream is2;
is2.open( "/Path/To/My/Shader/shader.frag.enc", ios::binary );

// get length of file:
is2.seekg( 0, ios::end );
lengthIN = is2.tellg();
is2.seekg( 0, ios::beg );

// allocate memory:
buffer_encIN = new char[ lengthIN ];

// read data as a block:
is2.read( buffer_encIN, lengthIN );
is2.close();


//// decryption ////

char mykey[EVP_MAX_KEY_LENGTH] = "changeit"; // also tried: unsigned char mykey[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
char iv[EVP_MAX_IV_LENGTH] = "01020304"; // also tried: unsigned char iv[] = {1,2,3,4,5,6,7,8};
int tmp_len = 0, in_len, out_len=0;
EVP_CIPHER_CTX ctx;

in_len = strlen( buffer_encIN );
char * buffer_dec = new char[ in_len ];

// decrypt
EVP_DecryptInit( &ctx, EVP_aes_256_cbc(), (unsigned char *)mykey, (unsigned char *)iv );
EVP_DecryptUpdate( &ctx, (unsigned char *)buffer_dec, &out_len, (unsigned char *)buffer_encIN, in_len );
tmp_len += out_len;
EVP_DecryptFinal( &ctx, (unsigned char *)&buffer_dec[ out_len ], &out_len );

printf( "Output:\n%s\n", buffer_dec );

我被两个问题困住了。首先,只有当我使用 -nosalt 选项时,大多数事情才能顺利进行,该选项不适用于部署。至少我得到 EVP_DecryptInit 和 *Update 返回 1,但 *Final 结果为 0:最后的几个字节被搞乱了。其次,使用完整版本(即使用盐)我根本无法启动和运行:(

简而言之:这是正确的方法吗,我只需要做我的作业(特别是关于盐/IV 的帮助,表示赞赏;) ),或者这只是花费了几个小时并且没有比应用一些 ROT13 方案来隐藏字符串更安全?

非常感谢任何帮助和评论!
马蒂亚斯

I would like to hide textual information (GLSL shaders in my case) used as strings in a C/C++ program, as they are directly readable within the binary. Therefore, I thought about encrypting the files during compile/build time and decrypt the data during runtime to continue with the reconstructed shaders.

However, I have some trouble in getting openssl on the console work together with the library (evp) in the C program. I have to admit that I am by no means an expert in cryptography but have to go in for this topic now...

Here's what I have tried:

// on the console:
openssl enc -aes-256-cbc -salt -in shader.frag -out shader.frag.enc

// ...

// in the program:

//// read enc file ////     
int lengthIN;
char * buffer_encIN;

ifstream is2;
is2.open( "/Path/To/My/Shader/shader.frag.enc", ios::binary );

// get length of file:
is2.seekg( 0, ios::end );
lengthIN = is2.tellg();
is2.seekg( 0, ios::beg );

// allocate memory:
buffer_encIN = new char[ lengthIN ];

// read data as a block:
is2.read( buffer_encIN, lengthIN );
is2.close();


//// decryption ////

char mykey[EVP_MAX_KEY_LENGTH] = "changeit"; // also tried: unsigned char mykey[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
char iv[EVP_MAX_IV_LENGTH] = "01020304"; // also tried: unsigned char iv[] = {1,2,3,4,5,6,7,8};
int tmp_len = 0, in_len, out_len=0;
EVP_CIPHER_CTX ctx;

in_len = strlen( buffer_encIN );
char * buffer_dec = new char[ in_len ];

// decrypt
EVP_DecryptInit( &ctx, EVP_aes_256_cbc(), (unsigned char *)mykey, (unsigned char *)iv );
EVP_DecryptUpdate( &ctx, (unsigned char *)buffer_dec, &out_len, (unsigned char *)buffer_encIN, in_len );
tmp_len += out_len;
EVP_DecryptFinal( &ctx, (unsigned char *)&buffer_dec[ out_len ], &out_len );

printf( "Output:\n%s\n", buffer_dec );

I am stuck here with two problems. First, most of the things work out nicely only if I use the -nosalt option, which is not applicable for deployment. At least I get EVP_DecryptInit and *Update to return 1, but *Final results in 0: several bytes at the end are messed up then. Second, using the full version (i.e. with salt) I cannot get things up and running at all :(

In a nutshell: is this the right approach and I just have to do my homework (help esp. on salt/IV appreciated ;)), or is this just spending hours and getting no more security than applying some ROT13 scheme to hide the string?

Any help and comments much appreciated!
Matthias

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自此以后,行同陌路 2024-10-21 10:52:28

从逆向工程的角度来看,我建议不要打扰。您的密钥也必须存储在您的应用程序中,并且与直接获取着色器相比,找到存储密钥的位置以及如何加密着色器稍微困难一些。根据我的经验,着色器中没有那么多专有代码,因此我建议您将其嵌入到明文中。

执行 ROT13 显然会更容易,并且可以阻止人们在您的二进制文件中搜索“vec3”等最简单的攻击。

您需要问自己的问题是:您试图阻止谁查看您的着色器源?不经意的观察者?在这种情况下,ROT13 可能就足够了。熟练的逆向工程师?那么您的进程内加密将不会提供太多保护。

如果您正在认真尝试保护数据并正在编写支持网络的应用程序,请考虑通过线路发送着色器,并在将着色器发送到 GPU 后清除内存。

Coming from the side of reverse engineering, I'd suggest to not bother. Your keys will have to be stored inside your app as well, and it's only marginally harder to find where you're storing keys and how you're encrypting your shaders than it is to just get at the shaders directly. In my experience, shaders don't have that much proprietary code in them as it is, so I'd suggest you just embed it in clear text.

Doing ROT13 would obviously be easier and thwart the simplest of attacks of people just searching your binaries for 'vec3' or the like.

The question you need to ask yourself is: who are you trying to prevent from looking at your shader source? The casual observer? In that case, a ROT13 might be sufficient. A skilled reverse engineer? Then your in-process encryption won't pose much of a protection.

If you are trying to protect your data in earnest and are writing a network-enabled application, consider sending your shaders over the wire and clearing your memory once they're sent to the GPU.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文