compile a c program in a encrypted way

Hi Guys,

I wonder I had have a look to the cc compile options but I could be missing one but basically I'm compliling a c program where I will storing a command to connect to a database and also userid and password. The issue is that after the module is generated using a command like strings I can see the the user and password in plain text. I wonder if anyone know if there is a option on the c compiler so I can encrypt the c module so the users or whoever will be granted to execute this module they don't get to see the user/password at all. I will be giving then execute access only so they shouldn't be able to view the file but want to make it extra secure if possible. thanks.

The answer is: don't hard code passwords.

One workaround is to encrypt the password into a file, then decrypt it at runtime. With a 600 permission the encrypted file is not a complete sitting duck for users on your system to play with. This also has some security issues, but is a lot better than just putting a password into a C source file. The best solution is to get the password interactively at run time.

if someone can execute the program they can read it. eg: debugger. don't hardcode a password as Jim suggested.

Hi Guys,

thanks. So I should be looking at makekey , keylogin and other commands to make this more robust. thanks again.

You may hardcode a password as long as it is not plain text. But doing so may offer a little advantage only - if ever - compared to the flexibility you gain having the password encrypted in a file.

Lo�c

Doesn't matter how you do it - if they can run the program, they can get the password using something like strace or truss.

Unless you make the process setuid or setgid, which opens up a whole new set of problems.

I can see the disavantage of having the password in plain text but haven't heard something really useful/mininful for someone who has come across to the same situation. It would be good to hear from someone to have been in similar situation and how they got around it. thanks.

I agree that "don't" isn't a helpful answer to "how do I do this", but it's probably a good one. Storing passwords is such a bad idea that most login systems have stern features to prevent you from using any.

As for alternatives -- it might help if you told us more about your problem. We don't even know if the database you're connecting to is on the same system, let alone what kind it is or what platform it runs on. There do exist secure, passwordless authentication systems like what ssh can use..

you should revist the design. split out the processes so the end-user does not have direct access to the database update. from a high level for example put a file/message on a queue; then another protected/privilieged process comes through and processes that message.

Thanks for your replies. I'll be looking at implementing some sort of encryption mechanism. It'll be a bit tricky becase basically the command that the script needs to execute is :

db2 connect to DBNAME user USERNAME using PASSWORD;

For some silly really with DB2 you have to make an explicit connection using the command above when connecting remotely. Usually we can get away having customers to schedule their jobs/scripts using control-M because it can execute any scripts taking over the access from other userid withoyut having to supply user/password when those scritps are executed locally on the server. But in this case the scripts needs to be executed remotely so..

But anyway I think I got some ideas that I should be testing soon. Thanks.

We know. For all the reasons we already explained, that doesn't work... Even if you encrypt it inside the executable, the code to decrypt it is built right into the executable for the convenience of any hacker. It even runs itself for them, they couldn't have it any better. Rube goldberg devices are not the way to go.

Can you "encrypt" the program's own arguments, anyway? The arguments themselves may be visible in /proc/ without security restriction.

So tunnel the connection in something that can be securely and passwordlessly authenticated, like ssh, so the DB connection can be made locally.

Here is one explicitly defined way to do it.

  1. create a file with 600 permissions just for the user, in a directory with 700 permissions.
    We'll call the file .data

  2. use crpyt (comes with most unixes)

# From your command line:  get a password with mixed characters then
# also create another password - this is a problem as well - the key for the password file
echo 'password' > clear.file

crypt key< clear.file >  .data
rm clear.file
  1. Now we have the key (another password to mess with)
# at the command line
key=keypassword
echo "$key" > .keepme
chmod 700 .keepme
  1. In your C code
FILE *fp=fopen( "/path/to/.keepme", "r");
FILE *cmd=NULL;
char tmp[32]={0x0};
char *p=NULL;
char cmdstring[128]={0x0};

fgets(tmp, sizeof(tmp), fp);
fclose(fp);
p=strchr(tmp, '\n');
if(p!=NULL) 
   *p=0x0;  /* lose the newline */
sprintf( cmdstring, "crypt %s < .data | pr", tmp);
cmd=popen(cmd, "r");
fgets(cmd, sizeof(tmp), cmd);
pclose(cmd);
# use pwd  to connect.
sprintf( myconnectstring, 
      "db2 connect to DBNAME user USERNAME using %s;", tmp);

This means that only root or the special user you have for the job can see the files. Be sure permissions are set correctly on your executable.

It is not hacker-proof by any means, but casual users will not be able to do much with. Be sure your .keepme and .data files are set correctly permissions-wise. There is no error checking in the code, it needs some.

now I know this code was not hacker-proof but the popen() call just allowed anyone on the system to capture the password by running the ps command(at the right time of course).

---------- Post updated at 22:22 ---------- Previous update was at 22:16 ----------

It's not really a silly reason to require credentials when connecting remotely. Do you really want the data to be accessible from anyone on your network? The reason the script works without a password when running on the database server is because the connection is over IPC and the user is already authenticated to the server. If you really don't want/need to authenticate users then set your authentication to CLIENT and then no password will be required. I highly recommend against doing that though.

If your at DB2 9.5 or higher have a look at TRUSTED CONTEXT. It can do things like this but provide greater controls then opening it up to the world.

Hi Jim,

I like this approach and I was testing it but the crypt command doesn't seems to be available on AIX.

Then you didn't see the reply immediately after it:

We know what you want to do but that idea is fundamentally flawed and cannot be made better. One way or another client code still knows how to generate the password, and feeds it as raw plaintext into other things, which really can't be made secure.

You have to try something completely different, like the many other suggestions made repeatedly in this thread, so the plaintext password doesn't need to be on your system.