Благодаря Точка Грегса в правильном направлении , было довольно легко скопировать генерацию Ключа и Начального вектора, которая происходила в EVP_BytesToKey () .
В основном они создают 48-байтовый массив (32-байтовый массив для ключа и 16-байтовый массив для IV) и используют SHA1 для хеширования закрытого ключа и 8 солт-байтов в этот буфер.Первый хеш - это только закрытый ключ и соль, а последующие хеши - это последний сгенерированный хеш, сцепленный с ключом и солт-байтами, до заполнения 48-байтового массива.
Ключ - это только первые 32 байта иIV - это последние 16 байтов.
Используя класс AESManaged из System.Security.Crytpography , а также ключ и IV, полученные из этого метода, я смог зашифровать свои пароли таким образом, чтобыСторонние разработчики, использующие библиотеки OpenSSL, могут расшифровать.
Вот алгоритм, который я использовал для получения ключа и начального вектора:
/// <summary>
/// Derives the key and IV.
/// </summary>
/// <param name="saltBytes">The salt bytes.</param>
/// <param name="privateKeyBytes">The private key bytes.</param>
/// <param name="iv">The iv.</param>
/// <returns>The Key</returns>
private static byte[] DeriveKeyAndIV(byte[] saltBytes, byte[] privateKeyBytes, out byte[] iv)
{
// we are creating a 16 byte initial vector and a 32 byte key
const int ivLength = 16;
iv = new byte[ivLength];
const int keyLength = 32;
var key = new byte[keyLength];
//SHA1 creates a 20 byte hash
const int hashLength = 20;
// container to store the hashed values
var keyContainer = new byte[keyLength + ivLength];
// munge together the privateKey and salt
var privateKeyAndSalt = new byte[privateKeyBytes.Length + saltBytes.Length];
Array.Copy(privateKeyBytes, privateKeyAndSalt, privateKeyBytes.Length);
Array.Copy(saltBytes, 0, privateKeyAndSalt, privateKeyBytes.Length, saltBytes.Length);
// use SHA1 crypto to match the -md SHA1 command line.
var sha1 = new SHA1CryptoServiceProvider();
// hashtarget holds the successive hash's source bytes.
var hashtarget = new byte[hashLength + privateKeyAndSalt.Length];
byte[] currentHash = null;
var bytesCopied = 0;
// do the hashing until we fill the container
while (bytesCopied < (ivLength + keyLength))
{
// Hash(0) is an empty set so just concatenate private key and salt.
if (currentHash == null)
{
currentHash = sha1.ComputeHash(privateKeyAndSalt);
}
else
{
// successive hashes are done on Hash(prev) + private key + salt.
Array.Copy(currentHash, hashtarget, currentHash.Length);
Array.Copy(privateKeyAndSalt, 0, hashtarget, currentHash.Length, privateKeyAndSalt.Length);
currentHash = hashtarget;
currentHash = sha1.ComputeHash(currentHash);
}
var copyAmount = Math.Min(currentHash.Length, keyContainer.Length - bytesCopied);
Array.Copy(currentHash, 0, keyContainer, bytesCopied, copyAmount);
bytesCopied += copyAmount;
}
// split out bytes in the container. first 32 are key, last 16 are iv.
Array.Copy(keyContainer, 0, key, 0, key.Length);
Array.Copy(keyContainer, key.Length, iv, 0, iv.Length);
return key;
}