There is a C # code that generates the key:

private static byte[] GenerateKey(string pass, int keyBytes = 32) { const int iterations = 300; var salt = new byte[] { 20, 30, 40, 50, 60, 70, 80, 90 }; var keyGenerator = new Rfc2898DeriveBytes(pass, salt, iterations); return keyGenerator.GetBytes(keyBytes); } 

Then, I get the key in base64:

 byte[] key = GenerateKey(pass); b64Key = Convert.ToBase64String(key); 

I rewrite in Python:

 def get_key(rand_key, keyBytes=32): iterations = 300 salt = bytes((20, 30, 40, 50, 60, 70, 80, 90)) derived_key = PBKDF2(rand_key, salt, iterations, keyBytes) return bytes(derived_key) 

I get a string in base64:

 key = get_key(random_string) b64Key = base64.b64encode(key.decode('utf-8')) 

Keys of different lengths are obtained at the output, although the key length seems to be 32 in both functions by default. Perhaps, the functionality from C # to Python is somehow incorrectly translated?

PS: the replacement of Rfc2898 by PBKDF2 is made according to this article: PBKDF2 Python keys vs .NET Rfc2898 . Python version used: 2.7.5. The PBKDF2 function is imported in this way:

 from pbkdf2 import PBKDF2 
  • from which package PBKDF2() function? What version of Python should the code work on? Give examples of input data ( pass ) and the corresponding result ( b64key ). The presence of calls bytes(derived_key) , b64encode(key.decode()) indicate possible problems with understanding how to work with binary data in Python. - jfs

1 answer 1

The problem was solved by trimming the key generated using Python code:

 def get_key(rand_key, keyBytes=32): iterations = 300 salt = bytes((20, 30, 40, 50, 60, 70, 80, 90)) derived_key = PBKDF2(rand_key, salt, iterations, keyBytes) #Переводим в байты ключ byte_key = bytes(derived_key) #Берём первые 32 байта split_key = byte_key[0:32] return bytes(split_key) 

However, perhaps this is not the best solution and not the only one. I would welcome comments and other solutions.