Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Obsolete all constructors for Rfc2898DeriveBytes #111678

Merged
merged 4 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/project/list-of-diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ The PR that reveals the implementation of the `<IncludeInternalObsoleteAttribute
| __`SYSLIB0057`__ | Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates. |
| __`SYSLIB0058`__ | KeyExchangeAlgorithm, KeyExchangeStrength, CipherAlgorithm, CipherAlgorithmStrength, HashAlgorithm and HashStrength properties of SslStream are obsolete. Use NegotiatedCipherSuite instead. |
| __`SYSLIB0059`__ | SystemEvents.EventsThreadShutdown callbacks are not run before the process exits. Use AppDomain.ProcessExit instead. |
| __`SYSLIB0060`__ | Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead. |

## Analyzer Warnings

Expand Down
6 changes: 4 additions & 2 deletions src/libraries/Common/src/System/Obsoletions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,7 @@ internal static class Obsoletions
internal const string EncryptionPolicyMessage = "EncryptionPolicy.NoEncryption and AllowEncryption significantly reduce security and should not be used in production code.";
internal const string EncryptionPolicyDiagId = "SYSLIB0040";

internal const string Rfc2898OutdatedCtorMessage = "The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.";
internal const string Rfc2898OutdatedCtorDiagId = "SYSLIB0041";
// SYSLIB0041 is no longer used and superseded by SYSLIB0060.
vcsjones marked this conversation as resolved.
Show resolved Hide resolved

internal const string EccXmlExportImportMessage = "ToXmlString and FromXmlString have no implementation for ECC types, and are obsolete. Use a standard import and export format such as ExportSubjectPublicKeyInfo or ImportSubjectPublicKeyInfo for public keys and ExportPkcs8PrivateKey or ImportPkcs8PrivateKey for private keys.";
internal const string EccXmlExportImportDiagId = "SYSLIB0042";
Expand Down Expand Up @@ -190,6 +189,9 @@ internal static class Obsoletions
internal const string SystemEventsEventsThreadShutdownMessage = "SystemEvents.EventsThreadShutdown callbacks are not run before the process exits. Use AppDomain.ProcessExit instead.";
internal const string SystemEventsEventsThreadShutdownDiagId = "SYSLIB0059";

internal const string Rfc2898DeriveBytesCtorMessage = "Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.";
vcsjones marked this conversation as resolved.
Show resolved Hide resolved
internal const string Rfc2898DeriveBytesCtorDiagId = "SYSLIB0060";

// When adding a new diagnostic ID, add it to the table in docs\project\list-of-diagnostics.md as well.
// Keep new const identifiers above this comment.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1134,17 +1134,21 @@ private static Rfc2898DeriveBytes OpenPbkdf2(
{
#if NET || NETSTANDARD2_1_OR_GREATER || NET472_OR_GREATER
#pragma warning disable CA5379
#pragma warning disable SYSLIB0060
return new Rfc2898DeriveBytes(
password,
salt,
iterationCount,
prf);
#pragma warning restore SYSLIB0060
#pragma warning restore CA5379
#else
if (prf == HashAlgorithmName.SHA1)
{
#pragma warning disable CA5379
#pragma warning disable SYSLIB0060
return new Rfc2898DeriveBytes(password, salt, iterationCount);
#pragma warning restore SYSLIB0060
#pragma warning restore CA5379
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1973,18 +1973,21 @@ public override void GenerateKey() { }
}
public partial class Rfc2898DeriveBytes : System.Security.Cryptography.DeriveBytes
{
[System.ObsoleteAttribute("The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.", DiagnosticId="SYSLIB0041", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations) { }
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { }
[System.ObsoleteAttribute("The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.", DiagnosticId="SYSLIB0041", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(string password, byte[] salt) { }
[System.ObsoleteAttribute("The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.", DiagnosticId="SYSLIB0041", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(string password, byte[] salt, int iterations) { }
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(string password, byte[] salt, int iterations, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { }
[System.ObsoleteAttribute("The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.", DiagnosticId="SYSLIB0041", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(string password, int saltSize) { }
[System.ObsoleteAttribute("The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.", DiagnosticId="SYSLIB0041", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(string password, int saltSize, int iterations) { }
[System.ObsoleteAttribute("Creating instances of Rfc2898DeriveBytes is obsolete. Use the static Pbkdf2 method instead.", DiagnosticId="SYSLIB0060", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public Rfc2898DeriveBytes(string password, int saltSize, int iterations, System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { }
public System.Security.Cryptography.HashAlgorithmName HashAlgorithm { get { throw null; } }
public int IterationCount { get { throw null; } set { } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,31 @@ public partial class Rfc2898DeriveBytes : DeriveBytes
/// </summary>
public HashAlgorithmName HashAlgorithm { get; }

[Obsolete(Obsoletions.Rfc2898OutdatedCtorMessage, DiagnosticId = Obsoletions.Rfc2898OutdatedCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations)
: this(password, salt, iterations, HashAlgorithmName.SHA1)
{
}

[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
: this(password, salt, iterations, hashAlgorithm, clearPassword: false)
{
}

[Obsolete(Obsoletions.Rfc2898OutdatedCtorMessage, DiagnosticId = Obsoletions.Rfc2898OutdatedCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(string password, byte[] salt)
: this(password, salt, 1000)
{
}

[Obsolete(Obsoletions.Rfc2898OutdatedCtorMessage, DiagnosticId = Obsoletions.Rfc2898OutdatedCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(string password, byte[] salt, int iterations)
: this(password, salt, iterations, HashAlgorithmName.SHA1)
{
}

[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(string password, byte[] salt, int iterations, HashAlgorithmName hashAlgorithm)
: this(
Encoding.UTF8.GetBytes(password ?? throw new ArgumentNullException(nameof(password))),
Expand All @@ -62,18 +64,19 @@ public Rfc2898DeriveBytes(string password, byte[] salt, int iterations, HashAlgo
{
}

[Obsolete(Obsoletions.Rfc2898OutdatedCtorMessage, DiagnosticId = Obsoletions.Rfc2898OutdatedCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(string password, int saltSize)
: this(password, saltSize, 1000)
{
}

[Obsolete(Obsoletions.Rfc2898OutdatedCtorMessage, DiagnosticId = Obsoletions.Rfc2898OutdatedCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
: this(password, saltSize, iterations, HashAlgorithmName.SHA1)
{
}

[Obsolete(Obsoletions.Rfc2898DeriveBytesCtorMessage, DiagnosticId = Obsoletions.Rfc2898DeriveBytesCtorDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public Rfc2898DeriveBytes(string password, int saltSize, int iterations, HashAlgorithmName hashAlgorithm)
{
ArgumentOutOfRangeException.ThrowIfNegative(saltSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,9 @@ public static void Pbkdf2_PasswordBytes_Compare(
HashAlgorithmName hashAlgorithmName = new HashAlgorithmName(hashAlgorithm);
byte[] key1;

#pragma warning disable SYSLIB0060 // Creating instances of Rfc2898DeriveBytes is obsolete.
using (Rfc2898DeriveBytes instanceKdf = new Rfc2898DeriveBytes(password, salt, iterations, hashAlgorithmName))
#pragma warning restore SYSLIB0060
{
key1 = instanceKdf.GetBytes(length);
}
Expand Down Expand Up @@ -253,7 +255,9 @@ public static void Pbkdf2_PasswordString_Compare(
HashAlgorithmName hashAlgorithmName = new HashAlgorithmName(hashAlgorithm);
byte[] key1;

#pragma warning disable SYSLIB0060 // Creating instances of Rfc2898DeriveBytes is obsolete.
using (Rfc2898DeriveBytes instanceKdf = new Rfc2898DeriveBytes(password, salt, iterations, hashAlgorithmName))
#pragma warning restore SYSLIB0060
{
key1 = instanceKdf.GetBytes(length);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using Test.Cryptography;
using Xunit;

#pragma warning disable SYSLIB0060 // Rfc2898DeriveBytes constructors are obsolete.

namespace System.Security.Cryptography
{
public class Rfc2898Tests
Expand Down Expand Up @@ -119,9 +121,7 @@ public static void Ctor_SaltCopied()
[Fact]
public static void Ctor_DefaultIterations()
{
#pragma warning disable SYSLIB0041 // Rfc2898DeriveBytes insecure constructor defaults
using (var deriveBytes = new Rfc2898DeriveBytes(TestPassword, s_testSalt))
#pragma warning restore SYSLIB0041
{
Assert.Equal(DefaultIterationCount, deriveBytes.IterationCount);
}
Expand Down Expand Up @@ -373,13 +373,11 @@ public static void CheckHashAlgorithmValue(HashAlgorithmName hashAlgorithm)
[Fact]
public static void CryptDeriveKey_NotSupported()
{
#pragma warning disable SYSLIB0041 // Rfc2898DeriveBytes insecure constructor defaults
#pragma warning disable SYSLIB0033 // Rfc2898DeriveBytes.CryptDeriveKey is obsolete
using (var deriveBytes = new Rfc2898DeriveBytes(TestPassword, s_testSalt))
{
#pragma warning disable SYSLIB0033 // Rfc2898DeriveBytes.CryptDeriveKey is obsolete
Assert.Throws<PlatformNotSupportedException>(() => deriveBytes.CryptDeriveKey("RC2", "SHA1", 128, new byte[8]));
#pragma warning restore SYSLIB0033
#pragma warning restore SYSLIB0041
}
}

Expand Down
Loading