I was looking for examples how to encode stuff in C using DES cypher and openssl headers and I found this one: http://www.codealias.info/technotes/des_encryption_using_openssl_a_simple_example
The code is almost perfect but I'm not so expert in this stuff and my C knowledge in C is not so big since I use it on PIC and AVR micro controllers...
Anyway in the code:
printf("Clear text\t : %s \n",clear);
memcpy(encrypted,Encrypt(key,clear,sizeof(clear)), sizeof(clear));
printf("Encrypted text\t : %s \n",encrypted);
memcpy(decrypted,Decrypt(key,encrypted,sizeof(clear)), sizeof(clear));
printf("Decrypted text\t : %s \n",decrypted);
As you can see, sizeof(clear) is used as the size of the string... the problem is that on the example we know the size of the text string... but when I'm sending this text over the network the other computer don't know it...
How can solve this issue... I don't understand so well why I need to have the size of the original string to decrypt :S
Thanks!!
The world is full of bad security systems designed by people who read Applied Cryptography.
Don't send your own 'encryptyed' stuff on wire. You're missing an HMAC, you're missing a key exchange protocol, you're missing a wire frame protocol (which is exactly the answer to your question 'how do I know the size'). Just use an off-the-shelf protocol like TLS/SSL. gnu-tls offers a easy to use API for SSL/TLS, openssl also supports it but is notoriously cumbersome to use. Whatever you do, don't start writing your own protocol, you'll come up with yet another broken 'encryption' protocol because of a bad key exchange or a 'optimized nonce' or a missing frame signature or whatever.
Here is a simple example using gnu-tls: Simple client example using the C++ API
In the implementations I have seen of DES, I only ever recall seeing plaintext and ciphertext of the same size. Wikipedia seems to confirm this. Since DES works on 64-bit chunks, that would make since as long as the code implementing DES properly pads the input to match those 64-bit boundaries. In fact, that's pretty much the definition of a block cipher (which is what DES is).
Thus I would wager you will see it work flawlessly with the other computer using the size of the encrypted text. A few tests of your own should be able to confirm this absolutely.
Also, I firmly agree with the Jeremy's comment that DES is a poor choice of encryption algorithm for most situations. Triple DES or AES are much better options.
Related
Question
I am wondering why do we connect to sockets by using functions like hton to take care of endianness when we could have sent the ip in plain char array.
Say we want to connect to 184.54.12.169
There is an explanation to this but I cannot figure out why we use integers instead of char, and so involving ourself in endianness hell.
I think char out_ip[] = "184.54.12.169" could have theoretically made it.
Please explain me the subtleties i don't get here.
The basic networking APIs are low level functions. These are very thin wrappers around kernel system calls. Removing these low level functions, forcing everything to use strings, would be rather bad for a low-level API like that, especially considering how tedious string handling is in C. As a concrete hurdle, even IP strings would not be fixed length, so handling them is a lot more complex than just plain 32 bit integers. And moving string handling to kernel is really quite against what kernel is supposed to be, handling arbitrary user strings is really user space problem.
So, you want to create higher-level functions which would accept strings and do the conversion in the library. But, adding such higher level "convenience" functions all over the place in the core libraries would bloat them, because certainly passing IP numbers is not the only place for such convenience. These functions would need to be maintained forever and included everywhere, after they became part of standard (official like POSIX, or de-facto) libraries.
So, removing the low-level functions is not really an option, and adding more functions for higher-level API in the same library is not a good option either.
So solution is to use another library to provide higher level networking API, which could for example handle address strings directly. Not sure what's out ther for C, but it's almost a given for other languages, which also have "real" strings built in so using them is not a hassle.
Because that's how an IP is transmitted in a packet. The "www.xxx.yyy.zzz" string form is really just a human readable form of a 4 byte integer that allows us to see the hierarchical nature a little easier. Sending a whole string would take up a lot more space as well.
Say number 127536 that requires 7 bytes not four. In addition you need to parse it.
I.e. more efficient and do not have to deal with invalid values.
novice to aes. in reading http://en.wikipedia.org/wiki/AES_implementations, I am a bit surprised. I should need just one function
char16 *aes128(char16 key, char16 *secrets, int len);
where char16 is an 8*16=128bit character type. and, presumably, ignoring memory leaks,
assert( bcmp( anystring, aes128(anykey, aes128(anykey, anystring, len), len )==0 );
I am looking over the description of the algorithm on wikipedia, and although I can see myself making enough coding mistakes to take me a few days to debug my own implementation, it does not seem too complex. maybe 100 lines? I did see versions in C#, such as Using AES encryption in C#. that seem themselves almost as long as the algorithm itself. earlier recommendations on stackoverflow mostly recommend the use of individual functions inside larger libraries, but it would be nice to have a go-to function for this task that one could compile into one's code.
so, is AES implementation too complex to be for the faint of heart? or is it reasonably short and simple?
how many lines does a C implementation take? is there a self-contained aes128() C function already in free form somewhere for the taking?
another question: is each block independently encoded? presumably, it would strengthen the encryption if the first block would create a salt that the second block would then use. otoh, this would mean that disk corruption of one block would make every subsequent block undecryptable.
/iaw
You're not seeing a single function like you expect because there are so many options. For example, the block encoding mechanism you described (CBC) is just one option or mode in AES encryption. See here for more information: http://www.heliontech.com/aes_modes_basic.htm
The general rule of thumb in any language is: Don't reinvent something that's already been done and done well. This is especially true in anything related to cryptography.
well using just the AES function is basically insecure as any block X will always be encoded to block Y with key K which is too much information to give an attacker... (according to cryptographers)
so you use some method to change the block cipher at each block. you can use a nonce or Cipher Block Chaining or some other method. but there is a pretty good example on wikipedia (the penguin picture): http://en.wikipedia.org/wiki/Electronic_code_book#Electronic_codebook_.28ECB.29
so in short you can implement AES in one function that is secure (as a block cipher), but it isn't secure if you have data that is longer than 16 bytes.
also AES is fairly complex because of all the round keys... I wouldn't really want to implement it, especially with all of the many good implementations around, but I guess it wouldn't be so bad if you had a good reason to do it.
so in short, to construct a secure stream cipher from a block cipher you need to adopt some strategy to change the effective key along the stream.
ok, so I found a reasonable standalone implementation:
http://www.literatecode.com/aes256
About 400 lines. I will probably use this one.
hope it helps others, too.
I'm using an Arduino platform with the Asynclabs library (an open-source wifi library for old yellowjacket and redback wifi boards).
Something is breaking the Arduino String object (note the capital S).
I'm using just a simple test:
Serial.println("Test Strings:\n");
String junk = "Do Strings print or what?";
Serial.println(junk);
while (1) { delay(2000); Serial.print("+");}
This prints as you'd expect at the start of my setup() block. When I move it to after the wifi.init() call, it still works. But when I move it after a call to a short network interaction, it is ignored as if it isn't there. No output is generated other than the first print w/o the String object.
Everything compiles okay - I'd have hoped the compiler would've told me if I had library collisions.
I grep'd thru the library files for other uses of the word 'String' and 'string' but have seen nothing much there. I renamed a file called strings.c to canned_strings.c. Still no improvement.
I'm at a bit of a loss. Any sugg of other things to look for?
[One note - I see several of the library files are including <string.h> - is this a deprecated Arduino lib file that should be switched to something else? Investigating... ]
-Ross
Ultimately it was clear that the String object is way too RAM intensive for the compact resources of the Arduino.
I got around the problem by eliminating all use of the String type from the code, and using char arrays with lots of pointers. This was much more RAM friendly.
[Also - in the Asynclabs Wifi library, it was helpful to reduce the size of the packet, to further free up some RAM. Highly recommended strategy to make any progress.]
is there any widely used procedure for hiding readable strings? After debugging my code i found a lot of plain text. I can use some simple encryption (Caesar cipher etc...) but this solution will totally slow down my code. Any ideas? Thanks for help
No, there is no widely used method for hiding referenced strings.
At some point an accessed string would have to be decrypted and this would reveal the key/method and your decryption becomes just obfuscation. If somebody wants to read all your referenced strings he could easily write some script to just convert them all to be readable.
I can't think of any reason to obfuscate strings like that. They are only visible to someone that analyses your executable. Those people would at the same time also be capable to reverse engineer your deobfuscation an apply it to all strings.
If secrecy of strings is vital to the security of your application, you have to rethink that.
Sidenote: There is no way that deciphering strings in C will slow down your application ...Except your application is full of strings and you do something very inefficient in the deciphering. Have you tested this?
The wikipedia page on TwoFish points at this reference implementation in C (and code) which is fine, but it lacks a main and my first few passes at implementing one didn't correctly process any of the "known vector" test cases I attempted. I suspect I'm looking at a problem of not using the API correctly but I have no idea where to start looking for the error. Rather than beat my head on that one, I'd rather start with a codebase that:
Runs out of the box
Has tests
Is self contained
Is written for clarity
I also have a strong preference for C or C like C++ code.
Note: I'm more interested in code readability than anything else at this point. Small, simple code that can encrypt and decrypt a single block and a main function that hard codes a call or three would be ideal. Most anything beyond that (like any user interface) will just be noise for my use case.
Also, anything that has a licence more restrictive than Boost will be useful to me only as an source of know good values and states to compare with.
I took an implementation by Neils Ferguson, one of the designers of Twofish, and wrapped it (very lightly, making very few changes) in C++, and it works well. I must strongly underline that I have done almost no work here, and don't claim to understand how Twofish works (and that's after reading up on it - but it's too hard for me to follow).
The constructor does comprehensive testing, and aborts if the tests fail, so once you have a fully constructed object you know it's going to work.
I've put the sources here: https://www.cartotype.com/assets/downloads/twofish/.
There are various configurable things in the files; one you might want to change is the abort function, Twofish_fatal, which in my version attempts to write to address 0 to force an exit, but that doesn't work on some platforms.
Like the code mentioned above, all this does is encode single 16-byte blocks (ECB = Electronic Code Book mode). But it's very easy to implement a better mode on top of it, like cipher bock chaining, in which each block of plain text is XORed with the previous block of cipher text before encrypting (use a random 'initialisation vector' of 16 bytes for the first block, and transmit that along with the encrypted data).
Another implementation can be found in the source code to Bruce Schneier's open-source password database program, PasswordSafe: the relevant sources are here: http://passwordsafe.git.sourceforge.net/git/gitweb.cgi?p=passwordsafe/pwsafe.git;a=tree;f=pwsafe/pwsafe/src/core;hb=HEAD. I haven't tried it so I can't comment on how easy it is to integrate.
The cryptcat package on Ubuntu and Debian provide a nc(1)-like functionality with twofish built in.
The twofish support is provided in twofish2.cc and twofish2.h in the source package. farm9crypt.cc provides a layer between C-style read() and write() functionality and the twofish algorithm -- it's in a style that I'd call C-like C++.
if you had taken just a minute to read
the reference implementation provided by libObfuscate
you would have found a cut'n'paste example of using TwoFish.
// Encrypt : outBuf [16] = Twofish ECB ( inBuf [16] )
TWOFISH_STATIC_DATA twofish;
BYTE passw [32];
BYTE inBuf [16] , outBuf [16];
memset( &twofish , 0 , sizeof( TWOFISH_STATIC_DATA ) );
Twofish_set_key( &twofish.key , ( DWORD * ) passw , 256 );
Twofish_encrypt( &twofish.key , ( DWORD * ) inBuf , ( DWORD * ) outBuf );
No serious REFERENCE IMPLEMENTATION would be
else but a single-block ECB implementation.
If you wish to encrypt more data you need to choose
the cipher-block chaining mode (CBC, ecc...) and apply it on top of ECB.
I eventually found this Python implementation derived from the C implamentation I listed above. The root cause of my issues turned out to be that the words of the key were in the wrong order.