我想隐藏在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,但*最终结果为0:最后几个字节混乱。其次,使用完整版本(即使用盐)我根本无法解决问题:(
简而言之:这是正确的方法,我只需要做我的功课(特别是盐/ IV赞赏;),或者这只是花费数小时而不是获得比使用一些ROT13方案更多的安全性隐藏字符串?
非常感谢任何帮助和评论! 的Matthias
答案 0 :(得分:2)
从逆向工程的角度来看,我建议不要打扰。您的密钥也必须存储在您的应用程序中,并且只是稍微难以找到您存储密钥的位置以及如何加密着色器而不是直接进入着色器。根据我的经验,着色器没有那么多专有代码,所以我建议你只是用明文嵌入它。
做ROT13显然会更容易,并且阻止人们只是在搜索你的二进制文件中搜索'vec3'之类的最简单的攻击。
您需要问自己的问题是:您是谁试图阻止查看着色器来源?不经意的观察者?在这种情况下,ROT13可能就足够了。熟练的逆向工程师?那么您的进程内加密不会带来太大的保护。
如果您正在努力保护数据并正在编写支持网络的应用程序,请考虑将着色器通过网络发送,并在将内存发送到GPU后清除内存。