2

Having read around on this issue on these posts (to name but two)...

Encrypting / Decrypting in vb.net does not always return the same value

C# PasswordDeriveBytes Confusion

...I was wondering if anyone knew the method that Microsoft use to key stretch their output?

To integrate with a system written in C# by someone else, I need to generate a large hash in PHP. The code that generates their SHA1 hash generates a 32 byte output, rather than the standard 20 byte SHA1 output. So has anyone cracked how Microsoft fill up the remaining 12 bytes? I've tried lots of combinations of appending the a SHA1 of the salt, password etc. as well as appending on previous iterations, but nothing seems to produce Microsoft's output.

I'm slightly concerned by this comment on https://stackoverflow.com/a/13482133/4346051...

"PasswordDeriveBytes uses an unknown, proprietary, non-deterministic, broken, cryptographically insecure method of key stretching for PasswordDeriveBytes"

Sample code as follows...

The C# code I need to replicate in PHP in order to produce the correct hash for integration with third party software:

string sPassword = "iudF98yfh9aRfhanifakdfn0a4ut-a8J789jasdpasd=";
string sSalt = "lYU7m+MDCvVWVQyuLIX3og==";
int iLength = 256 / 8;
byte[] saltInBytes = Encoding.ASCII.GetBytes(sSalt);

PasswordDeriveBytes password = new PasswordDeriveBytes(sPassword, saltInBytes, "SHA1", 2);

byte[] keyBytes = password.GetBytes(iLength);

Console.WriteLine("\nkeyBytes = \n");

foreach (byte value in keyBytes)
{
    Console.WriteLine(value);
}

...which outputs...

0
176
172
127
35
113
212
85
123
19
71
65
23
127
84
165
163
225
80
207
67
125
128
205
188
248
103
52
23
245
111
20

My PHP code for the same functionality is...

$sPassword = "iudF98yfh9aRfhanifakdfn0a4ut-a8J789jasdpasd=";
$sSalt = "lYU7m+MDCvVWVQyuLIX3og==";
$iIterations = 2;
$iLength = 256 / 8;

// combine password with salt
$key = $sPassword.$sSalt;

// perform sha1 how ever many times, using raw binary output instead of hex
for($i = 1; $i <= $iIterations; $i++) { 
    $key = sha1($key, true); 
}

// get the iLength number of chars
$key = substr($key, 0, $iLength);

$aKeyBytes = unpack('C*', $key);

print_r($aKeyBytes); 

...and this outputs...

Array
(
    [1] => 0
    [2] => 176
    [3] => 172
    [4] => 127
    [5] => 35
    [6] => 113
    [7] => 212
    [8] => 85
    [9] => 123
    [10] => 19
    [11] => 71
    [12] => 65
    [13] => 23
    [14] => 127
    [15] => 84
    [16] => 165
    [17] => 163
    [18] => 225
    [19] => 80
    [20] => 207
)

...but as you can see, we're 12 "bytes" short.

Unfortunately, it has to be replicated - I can't amend the C# to use a better method - I have no control over that side - my PHP code has to generate it

Community
  • 1
  • 1
Nick Allan
  • 21
  • 3
  • The first 20 bytes from `PasswordDeriveBytes` are as the PBKDF1 spec describes. The rest is a Microsoft specific extension. I'm not aware of any public documentation/specification for extension. – CodesInChaos Dec 10 '14 at 16:16
  • So all you can do is reverse engineer `PasswordDeriveBytes` or find a writeup somebody else created. But that might have some undesired legal implications. – CodesInChaos Dec 10 '14 at 16:17
  • Thanks for your reply - that's a shame RE: documentation - I couldn't find any either or a writeup - hopefully someone, somewhere will have figured it out and reply :S – Nick Allan Dec 10 '14 at 16:52
  • @NickAllan the best way to solve this problem is to make a command line application in c# and get the result from PHP `exec()` function – Hmmm Dec 10 '14 at 17:41
  • Tags should be relatively common, otherwise you won't alert any "followers" of tags on the new questions. On crypto.stackexchange.com I can just follow the entire feed, but obviously that is not possible on SO. Just "cryptography" is fine. – Maarten Bodewes Dec 10 '14 at 17:54
  • CodingInsane - thanks for your suggestion; I did consider that, however it would require a Microsoft .NET C# runtime and that doesn't exist on a Linux server - the Mono developers have said it's an issue that isn't, in fact, an issue and have closed off as a "no-fix" as their developers. ie. they're doing it right and Microsoft are doing it wrong. Just need to find out how they're doing it wrong!! – Nick Allan Dec 11 '14 at 12:32
  • See [What is the algorithm behind PasswordDeriveBytes? on crypto.se](http://crypto.stackexchange.com/questions/22271/what-is-the-algorithm-behind-passwordderivebytes) – CodesInChaos Jan 14 '15 at 11:25

1 Answers1

-1

I needed more or less the same thing - data encrypted using AES256-CBC in PHP that I needed to be able to decrypt using VB code.

Took me a while to search the internet and test various code samples, but I was able to get it working using information from the following posts:

Kind regards,

Sven

Community
  • 1
  • 1