|
security
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Rijndael decryption succeeds SOMETIMESit to produce an crypto key, which is then used to encrypt and decrypt. What we are finding is that it works on most machines all the time (throws "PKCS7 padding is invalid ..." when invalid passphrase passed - probably not a perfect check) but not on all of the machines and not all the time. Sometimes you can give it a passphrase and the decryption of the encrypted information will work. Also, in this case, the decrypted info will be different than what it should be. What am I doing wrong? Why is it sometimes working on invalid passphrases? Here's the code: public static byte[] Decrypt(byte[] cipherText_, byte[] salt_, byte[] iv_, string passPhrase_) { byte[] plainText = new byte[cipherText_.Length]; byte[] temp; using(MemoryStream cipherStream = new MemoryStream(cipherText_)) { //hash password PasswordDeriveBytes key = new PasswordDeriveBytes(passPhrase_, salt_, PasswordDeriveHashName, PasswordDeriveIterations); //Encrypt SymmetricAlgorithm sa = RijndaelManaged.Create(); ICryptoTransform decryptor = sa.CreateDecryptor(key.GetBytes(32), iv_); CryptoStream cryptoStream = new CryptoStream(cipherStream, decryptor, CryptoStreamMode.Read); int read = cryptoStream.Read(plainText, 0, plainText.Length); temp = new byte[read]; Array.Copy(plainText, 0, temp, 0, read); } return temp; } Derek, I remember a like question on a web farm. The answer had to do with
the seed value the crypto routines were using to get fired up. The default is autogenerate which will cause your application to require processor affinity to work--so it will work on one machine or the other, but it won't span two machines. The solution was to set the seed value to all the cpus in the web farm to the same value and that way your app could pick up where it left off on any cpu. Your description smells like you might be encountering the same type of issue; but this could be totally wrong because I don't know anything of Rijndael...Chuck Show quoteHide quote "Derek Knudsen" wrote: > I'm working on a solution that takes a random passphrase of a user and hashes > it to produce an crypto key, which is then used to encrypt and decrypt. What > we are finding is that it works on most machines all the time (throws "PKCS7 > padding is invalid ..." when invalid passphrase passed - probably not a > perfect check) but not on all of the machines and not all the time. > Sometimes you can give it a passphrase and the decryption of the encrypted > information will work. Also, in this case, the decrypted info will be > different than what it should be. What am I doing wrong? Why is it > sometimes working on invalid passphrases? Here's the code: > > public static byte[] Decrypt(byte[] cipherText_, byte[] salt_, byte[] iv_, > string passPhrase_) > { > byte[] plainText = new byte[cipherText_.Length]; > byte[] temp; > > using(MemoryStream cipherStream = new MemoryStream(cipherText_)) > { > //hash password > PasswordDeriveBytes key = new PasswordDeriveBytes(passPhrase_, salt_, > PasswordDeriveHashName, PasswordDeriveIterations); > > //Encrypt > SymmetricAlgorithm sa = RijndaelManaged.Create(); > ICryptoTransform decryptor = sa.CreateDecryptor(key.GetBytes(32), iv_); > CryptoStream cryptoStream = new CryptoStream(cipherStream, decryptor, > CryptoStreamMode.Read); > int read = cryptoStream.Read(plainText, 0, plainText.Length); > temp = new byte[read]; > Array.Copy(plainText, 0, temp, 0, read); > } > return temp; > } > > > I was wondering if it was something hardware related! The test machines we
have are dual-proc, while our dev machines are single proc. I don't know if what your saying applies to HT procs as well but I will try turning HT on on one machine to see if we start seeing the inconsistency. Thanks, Chuck! Show quoteHide quote "chuck rudolph" wrote: > Derek, I remember a like question on a web farm. The answer had to do with > the seed value the crypto routines were using to get fired up. The default is > autogenerate which will cause your application to require processor affinity > to work--so it will work on one machine or the other, but it won't span two > machines. The solution was to set the seed value to all the cpus in the web > farm to the same value and that way your app could pick up where it left off > on any cpu. Your description smells like you might be encountering the same > type of issue; but this could be totally wrong because I don't know anything > of Rijndael...Chuck > > "Derek Knudsen" wrote: > > > I'm working on a solution that takes a random passphrase of a user and hashes > > it to produce an crypto key, which is then used to encrypt and decrypt. What > > we are finding is that it works on most machines all the time (throws "PKCS7 > > padding is invalid ..." when invalid passphrase passed - probably not a > > perfect check) but not on all of the machines and not all the time. > > Sometimes you can give it a passphrase and the decryption of the encrypted > > information will work. Also, in this case, the decrypted info will be > > different than what it should be. What am I doing wrong? Why is it > > sometimes working on invalid passphrases? Here's the code: > > > > public static byte[] Decrypt(byte[] cipherText_, byte[] salt_, byte[] iv_, > > string passPhrase_) > > { > > byte[] plainText = new byte[cipherText_.Length]; > > byte[] temp; > > > > using(MemoryStream cipherStream = new MemoryStream(cipherText_)) > > { > > //hash password > > PasswordDeriveBytes key = new PasswordDeriveBytes(passPhrase_, salt_, > > PasswordDeriveHashName, PasswordDeriveIterations); > > > > //Encrypt > > SymmetricAlgorithm sa = RijndaelManaged.Create(); > > ICryptoTransform decryptor = sa.CreateDecryptor(key.GetBytes(32), iv_); > > CryptoStream cryptoStream = new CryptoStream(cipherStream, decryptor, > > CryptoStreamMode.Read); > > int read = cryptoStream.Read(plainText, 0, plainText.Length); > > temp = new byte[read]; > > Array.Copy(plainText, 0, temp, 0, read); > > } > > return temp; > > } > > > > > > Hi,
Results that you get is what should be expected. PKCS7 is padding scheme when each padding byte equal to the number of all padding bytes. I.e. if it is only 1 byte padding, then padding byte contains 0x01. Decryptor is not aware of number of padding bytes used. It just checks if it got valid padding. In case if last byte is 0x01 - decryptor consider it to be valid one byte padding. But with one byte padding you have about 1/256 probability that a random AES key would produce 0x01 after decryption. In other words - if you try many-many attempts to decrypt any cipher with random AES key, at least one key out of each 256 keys would decrypt one padding byte correctly and therefore would not report padding error. The plain text in these cases would be just some random binary garbage. -Valery. http://www.harper.no/valery Show quoteHide quote "Derek Knudsen" <Derek Knud***@discussions.microsoft.com> wrote in message news:ED5FB49F-7A60-4F90-9EB9-B70298E39A41@microsoft.com... > I'm working on a solution that takes a random passphrase of a user and > hashes > it to produce an crypto key, which is then used to encrypt and decrypt. > What > we are finding is that it works on most machines all the time (throws > "PKCS7 > padding is invalid ..." when invalid passphrase passed - probably not a > perfect check) but not on all of the machines and not all the time. > Sometimes you can give it a passphrase and the decryption of the encrypted > information will work. Also, in this case, the decrypted info will be > different than what it should be. What am I doing wrong? Why is it > sometimes working on invalid passphrases? Here's the code: > > public static byte[] Decrypt(byte[] cipherText_, byte[] salt_, byte[] iv_, > string passPhrase_) > { > byte[] plainText = new byte[cipherText_.Length]; > byte[] temp; > > using(MemoryStream cipherStream = new MemoryStream(cipherText_)) > { > //hash password > PasswordDeriveBytes key = new PasswordDeriveBytes(passPhrase_, salt_, > PasswordDeriveHashName, PasswordDeriveIterations); > > //Encrypt > SymmetricAlgorithm sa = RijndaelManaged.Create(); > ICryptoTransform decryptor = sa.CreateDecryptor(key.GetBytes(32), iv_); > CryptoStream cryptoStream = new CryptoStream(cipherStream, decryptor, > CryptoStreamMode.Read); > int read = cryptoStream.Read(plainText, 0, plainText.Length); > temp = new byte[read]; > Array.Copy(plainText, 0, temp, 0, read); > } > return temp; > } > > > I already answered why you get no padding error reported in my prev. post to
that thread. Here is another thing concerning your use of 256 bit AES key. First of all this is completely redundant - you just using unnecessary processor cycles on larger round keys schedule and extra AES round for nothing. AES is not the weakest link in your program. Do you know that to match 256 bits key strength you need a really strong and quite random alphanumeric password of size at least 40 characters? Do you really believe that someone would be able to remember that kind of password? And despite some common paranoia - 2^128 is a much bigger number than it seems. I believe that 128 bit AES is not something we will se broken in our life time unless some extraordinary breakthrough – like ability to transfer information with the speed much faster than speed of light and store information on units of size smaller than size of electrons. Here are just a few simple calculations: Electrical signal is conveyed with the speed about 70% of speed of the light. i.e. 210000000 (10^8.322219295) meters per second; If you consider two circuits placed on distance of 50 nanometers (non-existent technology that would not be available in at least next 4-8 years if Moore's law would not choke up during that time), then just for electrical signal being able to pass between these two circuits 2^128 times it would take 10^(128/log2(10)+log10(0.00000005)-log10(210000000)) = 8.10196*10^22 seconds or 9.37727*10^17 days (2.56912*10^15 years - much longer that total existence of the solar system J) ). Now suppose we talk about latest IBM supercomputer that is able to perform 65 terraflops (65 * 10^9 floating point calculation per second). 2^128 is about 10^38.5 i.e. 10^29 seconds to perform 2^128 floating point operations on that supercomputer. The earth surface is about 0.51 * 10^15 square meters. If we imagine impossible – that such supercomputer has dimensions of only one cubic meter (while as in reality it takes hundreds times more than that), then you have to cover whole earth surface including ocean with these supercomputers almost 200000 times (ie. put 200000 layers of these super computers on top of each other) to perform that many floating point operations per one year. And if you talk about decryption operation - one decryption operation is many times slower than one floating point operation. It's very much unlikely that 2^128 operations will be achievable in our lifetime (unless some extreme breakthroughs would allow us to transmit information much faster than the speed of light with using some particles that are much smaller than the size of electrons). The only concern of people talking about security of 128 bit keys is birthday paradox that means that with f.e. CBC mode of operations you are risking to leak information about one plain text block after you transmit 2^64 blocks of data with using single encryption key (i.e.. with 128 bit blocks its about 10000000 Terabytes of data). If you ask me - I would not be worry about that. -Valery. http://www.harper.no/valery P.S. here are just a few facts about the Earth: diameter:10^7 × 1.27 m, area: 10^15 × 0.510 m2, volume: 10^21 × 1.1 m3, density: 10^3 × 5.5 kg/m3 (5.5 g/cm3), mass: 10^25 × 0.60 kg Show quoteHide quote "Derek Knudsen" <Derek Knud***@discussions.microsoft.com> wrote in message news:ED5FB49F-7A60-4F90-9EB9-B70298E39A41@microsoft.com... > I'm working on a solution that takes a random passphrase of a user and > hashes > it to produce an crypto key, which is then used to encrypt and decrypt. > What > we are finding is that it works on most machines all the time (throws > "PKCS7 > padding is invalid ..." when invalid passphrase passed - probably not a > perfect check) but not on all of the machines and not all the time. > Sometimes you can give it a passphrase and the decryption of the encrypted > information will work. Also, in this case, the decrypted info will be > different than what it should be. What am I doing wrong? Why is it > sometimes working on invalid passphrases? Here's the code: > > public static byte[] Decrypt(byte[] cipherText_, byte[] salt_, byte[] iv_, > string passPhrase_) > { > byte[] plainText = new byte[cipherText_.Length]; > byte[] temp; > > using(MemoryStream cipherStream = new MemoryStream(cipherText_)) > { > //hash password > PasswordDeriveBytes key = new PasswordDeriveBytes(passPhrase_, salt_, > PasswordDeriveHashName, PasswordDeriveIterations); > > //Encrypt > SymmetricAlgorithm sa = RijndaelManaged.Create(); > ICryptoTransform decryptor = sa.CreateDecryptor(key.GetBytes(32), iv_); > CryptoStream cryptoStream = new CryptoStream(cipherStream, decryptor, > CryptoStreamMode.Read); > int read = cryptoStream.Read(plainText, 0, plainText.Length); > temp = new byte[read]; > Array.Copy(plainText, 0, temp, 0, read); > } > return temp; > } > > > I'm not sure if you are having these problems, but I have solved a similar
problem that has been troubling me all afternoon.... 1. Check the IV is the same in the decrypt as encrypt (I am sure you already know this). 2. If you are converting bytes to text using an ASCIIEncoder, or any other 8-bit encoder, it will only convert using 8-bits, i.e. a byte value of 129 will become 1!! I had this problem because the MSDN sample uses an ASCII encoder! How annoying!!!!! I hope this helps. Show quoteHide quote "Derek Knudsen" wrote: > I'm working on a solution that takes a random passphrase of a user and hashes > it to produce an crypto key, which is then used to encrypt and decrypt. What > we are finding is that it works on most machines all the time (throws "PKCS7 > padding is invalid ..." when invalid passphrase passed - probably not a > perfect check) but not on all of the machines and not all the time. > Sometimes you can give it a passphrase and the decryption of the encrypted > information will work. Also, in this case, the decrypted info will be > different than what it should be. What am I doing wrong? Why is it > sometimes working on invalid passphrases? Here's the code: > > public static byte[] Decrypt(byte[] cipherText_, byte[] salt_, byte[] iv_, > string passPhrase_) > { > byte[] plainText = new byte[cipherText_.Length]; > byte[] temp; > > using(MemoryStream cipherStream = new MemoryStream(cipherText_)) > { > //hash password > PasswordDeriveBytes key = new PasswordDeriveBytes(passPhrase_, salt_, > PasswordDeriveHashName, PasswordDeriveIterations); > > //Encrypt > SymmetricAlgorithm sa = RijndaelManaged.Create(); > ICryptoTransform decryptor = sa.CreateDecryptor(key.GetBytes(32), iv_); > CryptoStream cryptoStream = new CryptoStream(cipherStream, decryptor, > CryptoStreamMode.Read); > int read = cryptoStream.Read(plainText, 0, plainText.Length); > temp = new byte[read]; > Array.Copy(plainText, 0, temp, 0, read); > } > return temp; > } > > >
local admin security question
AzMan threading problems How to run aspnet with system account web application can not access event log Difference between VS2003 / VS20005 causes CRYPTO BAD DATA excepti Cannot Run Application on Windows Server 2003 Cannot run program from network drive User's Privileges Forms authentication to enter a static website ?cannot be instantiated under a partially trusted security policy (AllowPartiallyTrustedCallersAttri |
|||||||||||||||||||||||