string encryption

Basile B. via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 1 15:56:48 PDT 2016


On Friday, 1 July 2016 at 22:23:23 UTC, Hiemlick Hiemlicker wrote:
> I know this is probably a lot to ask for an many won't see the 
> point, but a secure program should not expose readable strings, 
> it makes it far too easy for the attacker to see what is going 
> on.
>
> Is it possible to encrypt every static string in D and decrypt 
> before it is output in an automatic fashion?
>
> Even something like
>
> e{This is an encrypted string}
>
> which encrypts the string using a user defined function(which 
> is ctfe'able) is better than nothing.
>
> Even a simple xor type of cypher is better than nothing. 
> Obviously optional.
>
> The problem is that there is no way to encrypt strings in the 
> binary through code because one must pass express the string 
> non-encrypted to the encryption function.
>
> encrypt("This string will still end up in the binary");
>
> even though the string is only used once, at the encryption 
> call site. It seems D won't replace
>
> encrypt("This string will still end up in the binary");
>
> with "skadf2903jskdlfaos;e;fo;aisjdfja;soejfjjfjfjfjfjfeij" or 
> whatever the ctfe value of encrypt actually is.
>
> This also seems like a bug in D because manifest constants used 
> as sole arguments to ctfe'able functions should be replaced by 
> the function result.
>
>
> e.g.,
>
> factorial(3) should be replaced by 6 and the function should 
> never be called at run time. This is the whole point of ctfe, 
> is it not?
>
> I'm not actually sure if the functions are ctfe'ed and the 
> un-encrypted string is just stored in the binary or what but 
> it's there
>
>
> import std.stdio;
>
> string e(string s)
> {
>     string q;
>     foreach(c; s)
>         q ~= c + 1;
>     return q;
> }
>
> void main()
> {
>    writeln(e("What is this string doing in the binary?"));
> }

You must make a template that follows this pattern:

     template KrypticString(string s)
     {
         string processor()
         {
             return /*do some stuff here on 's'*/ "";
         }
         enum KrypticString = processor();
     }

It's already used in phobos for example for octal() and 
hexString(). Also seen i dont remember where, for a float format.

But another important thing is that you must absolutely not 
release with -debug.
Strings are a thing but every one who has made the thug with IDA 
knows that the most usefull informations are the "Names" and not 
the "strings". The calls to the OS API can't be easily hidden, 
they are always in the "Names" but D functions names can.

For example it's even not worth crypting the strings if the 
attacker can see

     _D4main7decryptFAyaZAya

in the "Names", because in this case he "just" has to put a 
breakpoint on the C3 of the matching function, look for the 
decrypted string in memory, and bookmark the static addresses of 
the parameters passed to this function during the execution.

Also, if you take a minute to think a bit you'll find that 
cryptic strings will hit the eyes of the attacker quite quickly: 
"mmmh why is the content crypted ?!, let's see that...".


More information about the Digitalmars-d mailing list