How to text my encryption routine

Hello,

I have a web client who will be storing sensitive data (credit card info, etc) on his site. So, I have the *fun* task of doing everything I can to make the data secure. I think, after a lot of research and hours of programming, that I have come up with a fairly secure encryption routine. However, still being fairly new to encryption, I am more than a little nervous implementing the code until I can test it.

Enter my current problem. How can I test the strength of my encryption? Does anyone know of services - free or otherwise - that will attempt to break my encryption, to see if it can be done? Am I worrying over nothing (doubtful)? I have learned enough to encrypt data, but I do not know where to begin testing to see if my encryption can be broken.

Any help would be GREATLY appreciated!

Thanks,

Matt

[855 byte] By [MattLindleya] at [2007-11-26 22:11:57]
# 1
Show us your code.
ejpa at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 2

Well, I am a little nervous about directly posting the code. Essentially, I combine the domain name where the assembly is running with a user supplied password and a random assortment of letters, numbers, and symbols.

Using that, I create a hash and an IV, with which I apply Rijndael encryption on the data. Then, using another random password (again, mixed letters, numbers and symbols - no actual words), I encrypt the results from the last encryption.

It seems that this should be fairly secure. However, I know that people much smarter than me could possibly find ways of cracking the code.

Any thoughts, or do I really *have* to post my code?

MattLindleya at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 3
> Any thoughts, or do I really *have* to post my code?Security comes from the keys, not from the algorithm used (Kerckhoff's Principle).
sabre150a at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 4

Your solution might sound "secure", but your code might not be..

Secrecy does not assure security..

open source systems might be more secure than "secret" ones because people can elaborate and give solutions on how to make it more secure.. Take for example many encryption algorithms..they are known to the world but still (some) are unhackable..

Just include parts of your code without revealing "secret" data..

despinaa at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 5

Fair enough. Here is the code. I adapted this from a tutorial I found on implementing encryption in C#. There are a number of steps, but it *seems* to work well.

Private RandomChars as String = "Some random charaters here"

Private RandomChars2 as String = "More random chars here"

'This is the code called to begin encryption.

Private Shared Function AESEncrypt(ByVal clearText As String, Optional ByVal UserPassword As String = "") As String

Dim clearBytes As Byte() = System.Text.Encoding.Unicode.GetBytes(clearText)

Dim encryptedData As Byte() = AESEncrypt(clearBytes, UserPassword)

Return Convert.ToBase64String(encryptedData)

End Function

'Overloaded. This is called by the previous AESEncrypt,

'after the raw data has been split to a Byte()

Private Shared Function AESEncrypt(ByVal clearData As Byte(), ByVal UserPassword As String) As Byte()

Dim ms As MemoryStream = New MemoryStream

Dim alg As Rijndael = Rijndael.Create()

Dim context As HttpContext = HttpContext.Current

alg.Key = CreateKey(BuildKeyString(UserPassword))

alg.IV = CreateIV(BuildKeyString(UserPassword))

Dim cs As CryptoStream = New CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write)

cs.Write(clearData, 0, clearData.Length)

cs.Close()

Dim encryptedData As Byte() = ms.ToArray()

'This causes a second pass at encryption, using recursion on the already encrypted data

If UserPassword <> RandomChars2 Then

encryptedData = AESEncrypt(encryptedData, RandomChars)

End If

Return encryptedData

End Function

Private Shared Function CreateKey(ByVal strPassword As String) As Byte()

Dim chrData() As Char = strPassword.ToCharArray

Dim intLength As Integer = chrData.GetUpperBound(0)

Dim bytDataToHash(intLength) As Byte

For i As Integer = 0 To chrData.GetUpperBound(0)

bytDataToHash(i) = CByte(Asc(chrData(i)))

Next

Dim SHA512 As New System.Security.Cryptography.SHA512Managed

Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)

Dim bytKey(31) As Byte

For i As Integer = 0 To 31

bytKey(i) = bytResult(i)

Next

Return bytKey 'Return the key.

End Function

Private Shared Function CreateIV(ByVal strPassword As String) As Byte()

Dim chrData() As Char = strPassword.ToCharArray

Dim intLength As Integer = chrData.GetUpperBound(0)

Dim bytDataToHash(intLength) As Byte

For i As Integer = 0 To chrData.GetUpperBound(0)

bytDataToHash(i) = CByte(Asc(chrData(i)))

Next

Dim SHA512 As New System.Security.Cryptography.SHA512Managed

Dim bytResult As Byte() = SHA512.ComputeHash(bytDataToHash)

Dim bytIV(15) As Byte

For i As Integer = 32 To 47

bytIV(i - 32) = bytResult(i)

Next

Return bytIV 'Return the IV.

End Function

Private Shared Function BuildKeyString(ByVal UserPassword As String) As String

Return Left(InternalPassword, 16) & Left(UserPassword & RandomChars, 16)

End Function

MattLindleya at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 6
Good reference about Kerckhoff's Principle - never heard of this before, but completely makes sense. The more I read about cryptography, the more it seems like another full time job just to learn enough about it to not feel like a complete *****. :)
MattLindleya at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 7

Heh - join the crowd. I've been messing about with crypto for quite a while, and still consider myself to be at best an educated layman.

RE your code - if you're using AES, you at least don't need to worry overly much about the algorithm. The weak point then becomes protecting your key, while stored, in transit, and in use.

The obfuscation-technique you're using scares me. Adding "domain and random chars" probably makes you feel -more- secure, but makes me feel less so. First, you may mistakenly believe that adding bits at your end means you don't have to be careful to secure the user's half while in transit. Not the case. If I'm The Bad Guy, and I intercept the user's key -and- know your algorithm, then the amount of brute-forcing I need to do is reduced to guessing your 'random characters'. (And remember, good crypto security starts by assuming the Bad Guy knows -exactly- what your algorithm is...) So - even doing this, you need to make sure the user's key is transmitted securely, always.

I'll let the -real- exprets in here comment, tho. In general, the most heartening thing about your posts is that you know how little you know, and are nervous. THAT is the sign of a good security programmer :)

Good luck,

Grant

ggaineya at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 8

I understand what you mean. I had originally added the domain name as a starting point for an encryption key. Once I realized that this could be easily guessed, I decided to add in my own random characters. Then, of course, I realized that there would be scenarios where another password might be necessary, for specific users. So, I ended up adding all this together - in an effort to trump any dictionary attacks on the encryption (I had read that a lot of encryption could be broken if simple words were all that was used in the encryption key).

Now, I should point out that, at this stage, I do not necessarily mean "user" to be an actual website visitor. For the moment, I have no plans to accept a specific user password in this process. What I mean, then, by user password, is a password supplied by the function/routine that would call the encryption process. So, - again, for the moment - I am not transmitting any of the components used in the key. Though, I certainly understand that risk, if I ever do.

I guess what I am getting at is that I added all these things together to come up with an encryption key that would be as near to impossible to break as I could get, even if someone knew one, or even two parts of the key.

Now, you mentioned that someone could still figure out my random characters. How likely is that, really? I understand that there are a finite number of letters, numbers, and symbols from which to guess, but if the length of that string is unknown, it seems that "guessing" the random parts would be extraordinarily unlikely.

MattLindleya at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 9

> Now, you mentioned that someone could still figure

> out my random characters. How likely is that, really?

> I understand that there are a finite number of

> letters, numbers, and symbols from which to guess,

> but if the length of that string is unknown, it seems

> that "guessing" the random parts would be

> extraordinarily unlikely.

Nope, you've answered the real issue. We often see folk posting here who have not thought through the implications of what they're doing nearly as fully as you have in your last post. So I jumped to the conclusion that you thought your random salt meant more than it does - apologies, I'm just bitter and cynical from too many years spent reading threads here :).

The only way to guess your random string is, of course, brute force. It's just that if the rest of your key ('user' pwd and domain) are easily guessed/unprotected, then there is only the random chars that need to be brute-forced, and if they are too few or too accessible, they aren't enough. Too often we see algorithm attempts here that are painfully bad; your scheme doesn't appear to fall into that category.

Overall, the most heartening thing I see in your description of your problem is that you're already aware of possible attack points, and you're worried. Paranoia goes a very long way in securing systems :).

If you're interested in learning more about crypto, the books that we recommend here, a lot, are these:

"Applied Cryptography," Bruce Schneier - Generally considered The Bible, lots of great stuff on crypto algorithms, implementation and history and use.

http://www.amazon.com/Applied-Cryptography-Protocols-Algorithms-Source/dp/0471128457/ref=pd_bbs_4/102-7754962-3448942?ie=UTF8&s=books&qid=1174911726&sr=8-4

"Practical Crypto", Ferguuson and Schneier - doesn't cover as much ground as Applied, is aimed more at hooking the various algorithms together in a decent crypto system.

http://www.amazon.com/Practical-Cryptography-Niels-Ferguson/dp/047122894X/ref=pd_bbs_sr_3/102-7754962-3448942?ie=UTF8&s=books&qid=1174911726&sr=8-3

Enjoy,

Grant

ggaineya at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 10

Grant,

First, a big thanks for taking the time to discuss this issue w/ me. It just reinforces my position on giving back to the developer community (I recently had a long discussion with my partner - knowledge sharing vs protecting proprietary designs/knowledge). I can easily state that without the help from developers from a large number of forums, I would probably not be where I am today.

Second, thank you for your comments, observations, and the book references. It is nice to know that my normally bad habit of worrying over every detail does actually have some valid applications! Since this will not likely be my last project involving the need to protect data, I will definitely look into these books.

I do find it amazing, however, that with all of the crackers/hackers out there, who spend so much time trying to break into websites and data systems, that nobody seems to have thought to sell their services to companies to help find any weak points. When I began this project, I never imagined that protecting the data would be the most difficult part - well, my eyes are open now. Even more surprising is how difficult it has been to find any way to test/trust the encryption process that I have written (written, that is, on the backbone of other developers' shared knowledge).

All we ever hear about in movies, television, and on the news, is how someone has broken into a website or a company database that was thought to be secure. So, it is difficult to trust that anything I can do will thwart attempts at breaking into my code or database, will be of any use. Having been a web developer for about 10 years now (mostly very small business websites), I've always known that "security by obscurity" is a fools bet, at best. However, what with all the different encryption algorithms out there, all the different opinions as to which is best, and the unfortunate number of articles written by those who truly do not know enough to be advising anyone, I can see how a newbie might get discouraged and give up.

Anyway, having given the matter more thought, and after this discussion, it does seem silly to include, in any portion of my key, something so easily guessed as the domain name. So, why not make the entire thing random? At this point, I do not need to gather a password from an actual user, so why include anything that could be guessed? Even if there eventually needs to be a user database store (credit cards or other account info), there is nothing that says I *must* use the users actual password to encrypt the data, is there? I could include any number of user data fields to create some salted hash, and still use a large number of random characters/symbols for the rest of the key and IV.

Thanks again for your help! Maybe one of these days, I will know enough to give back to this forum.

Matt

MattLindleya at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...
# 11

<snip>

> Second, thank you for your comments, observations,

> and the book references. It is nice to know that my

> normally bad habit of worrying over every detail does

> actually have some valid applications! Since this

> will not likely be my last project involving the need

> to protect data, I will definitely look into these

> books.

I have them right in front of me at all times. Two of the best books I have ever bought.

>

> I do find it amazing, however, that with all of the

> crackers/hackers out there, who spend so much time

> trying to break into websites and data systems, that

> nobody seems to have thought to sell their services

> to companies to help find any weak points.

There are companies that will do just this.

> When I

> began this project, I never imagined that protecting

> the data would be the most difficult part - well, my

> eyes are open now. Even more surprising is how

> difficult it has been to find any way to test/trust

> the encryption process that I have written (written,

> that is, on the backbone of other developers' shared

> knowledge).

Whenever I used to get involved in site/program security (I'm now retired) I used to suggest that a Security Consultant was hired to do a full security review. I always used to put this suggestion in writing so as to protect my backside and only once did I get any real resistance. Most project managers don't like the idea of spending the money but when you point out that if they don't spend the money and there is a security breach then their necks are on the block then they quickly authorize the spend.

>

> All we ever hear about in movies, television, and on

> the news, is how someone has broken into a website or

> a company database that was thought to be secure. So,

> it is difficult to trust that anything I can do will

> thwart attempts at breaking into my code or database,

> will be of any use. Having been a web developer for

> about 10 years now (mostly very small business

> websites), I've always known that "security by

> obscurity" is a fools bet, at best. However, what

> with all the different encryption algorithms out

> there, all the different opinions as to which is

> best, and the unfortunate number of articles written

> by those who truly do not know enough to be advising

> anyone, I can see how a newbie might get discouraged

> and give up.

The encryption algorithms are not really the problem. Up to a couple of years ago one used 1024 bit RSA and 3DES and these days one uses 2048 RSA and AES. These may or may not be the best one can use but that does not matter because these are the industry standard. One won't get sacked if someone finds a hole in either of them. If one goes against the industry standard and the algorithms one uses are shown to be flawed then one has some fast talking to do trying to explain why one went against the industry standard.

The main problems are the ones that you seem to be struggling with i.e. the protocol to be used with the encryption algorithms and key protection. Both of these are difficult problems.

>

> Anyway, having given the matter more thought, and

> after this discussion, it does seem silly to include,

> in any portion of my key, something so easily guessed

> as the domain name. So, why not make the entire thing

> random? At this point, I do not need to gather a

> password from an actual user, so why include anything

> that could be guessed? Even if there eventually needs

> to be a user database store (credit cards or other

> account info), there is nothing that says I *must*

> use the users actual password to encrypt the data, is

> there? I could include any number of user data fields

> to create some salted hash, and still use a large

> number of random characters/symbols for the rest of

> the key and IV.

>

> Thanks again for your help! Maybe one of these days,

> I will know enough to give back to this forum.

> Matt

Your responses already give something back to the forum. They will encourage readers to think before they code.

sabre150a at 2007-7-10 11:00:53 > top of Java-index,Security,Cryptography...