

Text Shredder: Peer-to-peer message-based encryption utility - stevehaunts
https://textshredder.codeplex.com/

======
sweis
This appears to be using AES-CBC without any authentication:

[https://textshredder.codeplex.com/SourceControl/latest](https://textshredder.codeplex.com/SourceControl/latest)

(HN breaks the link directly to the code, but add this fragment to go straight
to the AES.cs class: "#Code/Release 1.0/ClientLibrary/CryptoProviders/AES.cs")

This is not secure and should include authentication. As far as I know, .NET
does not include authenticated cipher modes by default:

[http://msdn.microsoft.com/en-
us/library/system.security.cryp...](http://msdn.microsoft.com/en-
us/library/system.security.cryptography.ciphermode\(v=vs.110\).aspx)

I recommend using a second HMAC key and computing a HMAC over both the IV and
ciphertext. Keyczar does something similar:

[https://code.google.com/p/keyczar/wiki/CiphertextFormat](https://code.google.com/p/keyczar/wiki/CiphertextFormat)

~~~
danbruc
Would you mind to elaborate in which way the use of AES-CBC makes the
encryption insecure?

~~~
sweis
CBC is okay if it is used to encrypt before MACing. The issue is that
TextShredder used CBC without any authentication, i.e. a MAC. That means
someone can modify the ciphertext in transit and it won't be detected. This
opens up several types of attacks. In theoretical terms, unauthenticated block
ciphers are not secure against adaptive chosen ciphertext attacks (CCA2). In
practical terms, one attack that comes to mind is a padding oracle attack.
Essentially, an attacker given a real message and can create modified
ciphertexts that will cause a decrypting party to potentially leak information
in a side channel.

Serge Vaudenay talked about this 12 years ago:

[http://www.iacr.org/cryptodb/archive/2002/EUROCRYPT/2850/285...](http://www.iacr.org/cryptodb/archive/2002/EUROCRYPT/2850/2850.pdf)

The recent Lucky 13 attack was a form of this type of padding oracle attack:

[https://www.imperialviolet.org/2013/02/04/luckythirteen.html](https://www.imperialviolet.org/2013/02/04/luckythirteen.html)

~~~
danbruc
I understand the point in the general case but I don't think you could exploit
it in this case. Nonetheless it would still be nicer if the application would
tell me that someone tampered with the message instead of making me infer it
from the fact that it partially decoded into garbage. Thanks!

~~~
stevehaunts
I will add in a hmac if the ciphertext and IV and alert the user if the
message has been tampered with. I will have it updated within the next week.

Thanks for the constructive feedback. This is why I posted it here and made it
open source so I could get peer review, make the utility better and learn a
few things along the way.

~~~
danbruc
One thing I would really suggest is to get rid of all this conversions between
strings and byte arrays, this adds unnecessarily complexity to the code.
Convert messages and passwords to byte arrays as soon as you get them,
preferably using a Unicode encoding to support foreign languages, and then
only work with byte arrays for everything until you finally want to output the
encrypted message where you probably want to Base64 encode it. Especially I
did not understand why you have these ugly methods in ByteHelpers when you
already have Encoding.GetString() and Encoding.GetBytes() and you are using
them in some places.

------
lucb1e
Uhm, why this if we have GPG? I've never heard of Text Shredder and
automatically distrust any new crypto (just look at Telegram), whereas GPG is
very well known and much more battle tested.

Edit: The download button gives me some .exe file and the source code is
Microsoft shit. Not gonna work.

Edit2: It seems to use AES ECB. Definitely secure... not
[https://en.wikipedia.org/wiki/File:Tux_ecb.jpg](https://en.wikipedia.org/wiki/File:Tux_ecb.jpg)

Pseudocode of what it does:

    
    
        function EncryptBlock(data, password)
          encrpytedMessage = aes.Encrypt(data, passwd, salt, pbkdf2RoundsCount);
          return encrpytedMessage; // sic
        
        function aes.Encrypt(data, pwd, salt, pwd_rounds)
          hash = pbkdf2(pwd, salt, rounds);
          IV = hash.getBytes(16);
          passwd = hash.getBytes(32);
          encrypted = aes(data, passwd, IV);
          return encrypted;

~~~
simplyinfinity
Microsoft shit? you realize this is an open source project, right? this didn't
come from microsoft, instead someone used the tools they provided to give you
a way of secure communication, and you go about and bash them because of what?
The tools they used are from Microsoft ?

~~~
lucb1e
> The tools they used are from Microsoft ?

That's the point. Microsoft doesn't release .NET compilers for any other
platform than their own, and since I don't use Windows I'm not going to
execute this application. Anyone sending messages to me can install GnuPG,
something that is available across platforms.

~~~
sp332
I just tested it, and the executable runs perfectly fine in Mono. Look ma, no
Microsoft!

------
danbruc
This is roughly what it does. I did not bother to figure out what the purpose
of the SHA256 hahses not mentioned here is. The code also converts between
byte arrays and strings using ASCII and UTF-16 encoding and Base64 encoded
data a thousand times so I might have lost track of this and the pseudo code
below is missing some encoding changes.

    
    
      salt = "$2a$10$67C.GOM1jShOBOM.f.BIAe" // Version 2a and work factor 10.
    
      password = BASE64-ENCODE(BCRYPT(password1 + password2, salt))
    
      rounds = 45000
    
      salt = CSRNG.GetBytes(32)
    
      key + iv = PBKDF2-HMAC-SHA1(password, salt, rounds).GetBytes(32 + 16)
    
      encrypted = BASE64-ENCODE(salt + AES-256-CBC(GZIP(message), key, iv))
    

The bcrypt implementation comes from [1].

[1] [http://bcrypt.codeplex.com/](http://bcrypt.codeplex.com/)

~~~
tptacek
I don't understand why this uses both bcrypt and PBKDF2.

The problem it tries to solve is turning a low-entropy passphrase into a 128
bit AES key. That's the problem that a KDF, like PBKDF2, solves.

If they want to make the system stronger, increase the PBKDF2 iterations; lose
the bcrypt step. (They could also use a better KDF, like scrypt, instead of
PBKDF2; PBKDF2 is fine, though).

Also, compressing breaks semantic security. Don't compress before encrypting.

 _Edited; briefly thought parent commenter was the author of the tool._

------
wtbob
Nice idea. I'm not certain what the purpose of the second password is, since
it appears from the documentation that both passwords are required if both are
given.

I think the UI is probably easier for a normal user than GPG or somesuch.

I've some strong concerns about the quality of the cypher construction though,
just from looking at the comments here.

~~~
stevehaunts
The idea is that it is easy to use. Gpg requires admin rights to install which
you may not always have, if on a corporate network for example. If u have
limited control on the machine or security of the network this utility gives
you an easy way to get message based security where u control the key.

------
natch
Being closed source makes this is highly suspect at the outset.

From my perspective it could be a trojan horse, even if the author claims
otherwise all day long.

Bottom line, its security cannot be verified, so this might as well be
considered dead in the water as far as being a viable tool for security.

Furthermore even if it was real, using it would limit your communication to
people who are running Windows...

Simple fix for all this: release it as an open source project.

~~~
tudborg
wat.

[https://textshredder.codeplex.com/SourceControl/latest](https://textshredder.codeplex.com/SourceControl/latest)
?

~~~
natch
Can this be compiled with an open source compiler? If not, I wouldn't trust
the results of any build.

------
aaronbasssett
echo "Secret message" | openssl enc -aes-256-cbc -a

