Windows Phone - низкая производительность шифрования - PullRequest
3 голосов
/ 08 сентября 2011

Я использовал следующий код для шифрования в Windows Phone:

public static string Encrypt(string dataToEncrypt, string password)
{
AesManaged aes = null;
MemoryStream memoryStream = null;
CryptoStream cryptoStream = null;
string salt = "12345678";

try
{
    // Generate a Key based on a Password and HMACSHA1 pseudo-random number generator
    // Salt must be at least 8 bytes long
    // Use an iteration count of at least 1000
    Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt), 10000);

    // Create AES algorithm
    aes = new AesManaged();

    // Key derived from byte array with 32 pseudo-random key bytes
    aes.Key = rfc2898.GetBytes(32);

    // IV derived from byte array with 16 pseudo-random key bytes
    aes.IV = rfc2898.GetBytes(16);

    // Create Memory and Crypto Streams
    memoryStream = new MemoryStream();
    cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write);

    // Encrypt Data
    byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt);
    cryptoStream.Write(data, 0, data.Length);
    cryptoStream.FlushFinalBlock();

    // Return Base 64 String
    return Convert.ToBase64String(memoryStream.ToArray());
}
finally
{
    if (cryptoStream != null)
    {
        cryptoStream.Close();
    }

    if (memoryStream != null)
    {
        memoryStream.Close();
    }

    if (aes != null)
    {
        aes.Clear();
    }
}
}

public static string Decrypt(string dataToDecrypt, string password)
{
AesManaged aes = null;
MemoryStream memoryStream = null;
string salt = "12345678";

try
{
    // Generate a Key based on a Password and HMACSHA1 pseudo-random number generator
    // Salt must be at least 8 bytes long
    // Use an iteration count of at least 1000
    Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt), 10000);

    // Create AES algorithm
    aes = new AesManaged();

    // Key derived from byte array with 32 pseudo-random key bytes
    aes.Key = rfc2898.GetBytes(32);

    // IV derived from byte array with 16 pseudo-random key bytes
    aes.IV = rfc2898.GetBytes(16);

    // Create Memory and Crypto Streams
    memoryStream = new MemoryStream();
    CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write);

    // Decrypt Data
    byte[] data = Convert.FromBase64String(dataToDecrypt);
    cryptoStream.Write(data, 0, data.Length);
    cryptoStream.FlushFinalBlock();

    // Return Decrypted String
    byte[] decryptBytes = memoryStream.ToArray();

    // Dispose
    if (cryptoStream != null)
    {
        cryptoStream.Dispose();
    }

    // Retval
    return Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
}
finally
{
    if (memoryStream != null)
    {
        memoryStream.Dispose();
    }

    if (aes != null)
    {
        aes.Clear();
    }
}
}

Производительность шифрования очень низкая. Кто-нибудь может предложить некоторые улучшения в приведенном выше коде?

Ответы [ 2 ]

3 голосов
/ 08 сентября 2011

Конечно, вы можете переместить код получения ключа, используя Rfc2898DeriveBytes, за пределы этой функции, поскольку ключ для данного пароля будет постоянным и обычно будет использоваться несколько раз. Кроме этого я не вижу много возможностей для улучшения.

1 голос
/ 08 сентября 2011

Возможно, вам следует ввести некоторые скобки using (), чтобы убедиться в отсутствии утечек памяти. Вы могли бы взглянуть на это:

http://zayko.net/post/How-to-EncryptDecrypt-a-String-in-Silverlight-for-Windows-Phone-7.aspx

Это поможет, только если ваша функция со временем замедлится, а не при первом запуске.

...