All rules
CA5379Security Enabled by default: No

Ensure key derivation function algorithm is sufficiently strong

Ensure key derivation function algorithm is sufficiently strong

Microsoft docs

Description

The System.Security.Cryptography.Rfc2898DeriveBytes class defaults to using the System.Security.Cryptography.HashAlgorithmName.SHA1 algorithm. When instantiating an System.Security.Cryptography.Rfc2898DeriveBytes object, you should specify a hash algorithm of System.Security.Cryptography.HashAlgorithmName.SHA256 or higher. Note that System.Security.Cryptography.Rfc2898DeriveBytes.HashAlgorithm property only has a get accessor.

Cause

Use of one of the following algorithms when instantiating System.Security.Cryptography.Rfc2898DeriveBytes:

  • System.Security.Cryptography.MD5
  • System.Security.Cryptography.SHA1
  • An algorithm that the rule can't determine at compile time

How to fix violations

Because System.Security.Cryptography.MD5 or System.Security.Cryptography.SHA1 are vulnerable to collisions, use System.Security.Cryptography.SHA256 or higher for the System.Security.Cryptography.Rfc2898DeriveBytes class.

Older versions of .NET Framework or .NET Core may not allow you to specify a key derivation function hash algorithm. In such cases, you need to upgrade the target framework version of .NET to use a stronger algorithm.

Example

using System.Security.Cryptography;

class ExampleClass
{
    public void ExampleMethod(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
    {
        var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.MD5);
    }
}

using System.Security.Cryptography;

class DerivedClass : Rfc2898DeriveBytes
{
    public DerivedClass (byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm) : base(password, salt, iterations, hashAlgorithm)
    {
    }
}

class ExampleClass
{
    public void ExampleMethod(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
    {
        var derivedClass = new DerivedClass(password, salt, iterations, HashAlgorithmName.MD5);
    }
}

using System.Security.Cryptography;

class DerivedClass : Rfc2898DeriveBytes
{
    public DerivedClass (byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm) : base(password, salt, iterations, hashAlgorithm)
    {
    }

    public HashAlgorithmName HashAlgorithm { get; set;}
}

class ExampleClass
{
    public void ExampleMethod(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
    {
        var derivedClass = new DerivedClass(password, salt, iterations, HashAlgorithmName.MD5);
        derivedClass.HashAlgorithm = HashAlgorithmName.SHA256;
    }
}

using System.Security.Cryptography;

class ExampleClass
{
    public void ExampleMethod(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
    {
        var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256);
    }
}

When to suppress

It is not recommended to suppress this rule except for application compatibility reasons.

Group results
0 yes 0 no
ConsensusNone (disabled)
Severity preference (yes voters)
Suggestion0
Warning0
Error0