CA5390: No codificar la clave de cifrado de forma rígida

Propiedad Value
Identificador de la regla CA5390
Título No codificar la clave de cifrado de forma rígida
Categoría Seguridad
La corrección interrumpe o no interrumpe Poco problemático
Habilitado de forma predeterminada en .NET 8 No

Causa

El parámetro key de los constructores System.Security.Cryptography.AesCcm o System.Security.Cryptography.AesGcm, la propiedad System.Security.Cryptography.SymmetricAlgorithm.Key o el parámetro rgbKey de los métodos System.Security.Cryptography.SymmetricAlgorithm.CreateEncryptor o System.Security.Cryptography.SymmetricAlgorithm.CreateDecryptor están codificados de forma rígida por uno de los siguientes elementos:

De forma predeterminada, esta regla analiza todo el código base, pero esto es configurable.

Descripción de la regla

Para que un algoritmo simétrico se realice correctamente, solo el remitente y el receptor deben conocer la clave secreta. Cuando una clave está codificada de forma rígida, se detecta fácilmente. Incluso con los archivos binarios compilados, es fácil que los usuarios malintencionados logren la extracción. Una vez que la clave privada está en peligro, el texto cifrado se puede descifrar directamente y ya no está protegido.

Cómo corregir infracciones

  • Considere la posibilidad de volver a diseñar la aplicación para que use un sistema de administración de claves seguro, como Azure Key Vault.
  • Mantenga las credenciales y las claves en una ubicación segura independiente del código fuente.

Cuándo suprimir las advertencias

No suprima las advertencias de esta regla.

Configuración del código para analizar

Use las opciones siguientes para configurar en qué partes del código base se va a ejecutar esta regla.

Puede configurar estas opciones solo para esta regla, para todas las reglas a las que se aplica o para todas las reglas de esta categoría (Seguridad) a las que se aplica. Para más información, vea Opciones de configuración de reglas de calidad de código.

Exclusión de símbolos específicos

Puede excluir símbolos específicos, como tipos y métodos, del análisis. Por ejemplo, para especificar que la regla no se debe ejecutar en ningún código dentro de los tipos con el nombre MyType, agregue el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Formatos de nombre de símbolo permitidos en el valor de opción (separados por |):

  • Solo nombre de símbolo (incluye todos los símbolos con el nombre, con independencia del tipo contenedor o el espacio de nombres).
  • Nombres completos en el formato de id. de documentación del símbolo. Cada nombre de símbolo necesita un prefijo de tipo símbolo, como M: para los métodos, T: para los tipos y N: para los espacios de nombres.
  • .ctor para los constructores y .cctor para los constructores estáticos.

Ejemplos:

Valor de la opción Resumen
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Coincide con todos los símbolos denominados MyType.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Coincide con todos los símbolos denominados MyType1 o MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Coincide con un método MyMethod concreto con la signatura completa especificada.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Coincide con los métodos MyMethod1 y MyMethod2 concretos con las signaturas completas especificadas.

Exclusión de tipos específicos y sus tipos derivados

Puede excluir tipos específicos y sus tipos derivados del análisis. Por ejemplo, para especificar que la regla no se debe ejecutar en ningún método dentro de los tipos con el nombre MyType y sus tipos derivados, agregue el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Formatos de nombre de símbolo permitidos en el valor de opción (separados por |):

  • Solo nombre de tipo (incluye todos los tipos con el nombre, con independencia del tipo contenedor o el espacio de nombres).
  • Nombres completos en el formato de identificador de documentación del símbolo, con un prefijo T: opcional.

Ejemplos:

Valor de la opción Resumen
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Coincide con todos los tipos denominados MyType y todos sus tipos derivados.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Coincide con todos los tipos denominados MyType1 o MyType2, y todos sus tipos derivados.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Coincide con un tipo MyType específico con el nombre completo dado y todos sus tipos derivados.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Coincide con los tipos MyType1 y MyType2 específicos con los correspondientes nombres completos y todos sus tipos derivados.

Ejemplos de pseudocódigo

Infracción de la matriz de bytes codificada de forma rígida

using System;
using System.Security.Cryptography;

class ExampleClass
{
    public void ExampleMethod(byte[] someOtherBytesForIV)
    {
        byte[] rgbKey = new byte[] {1, 2, 3};
        SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
        rijn.CreateEncryptor(rgbKey, someOtherBytesForIV);
    }
}

Infracción de Convert.FromBase64String codificada de forma rígida

using System;
using System.Security.Cryptography;

class ExampleClass
{
    public void ExampleMethod(byte[] someOtherBytesForIV)
    {
        byte[] key = Convert.FromBase64String("AAAAAaazaoensuth");
        SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
        rijn.CreateEncryptor(key, someOtherBytesForIV);
    }
}

Infracción de Encoding.GetBytes codificada de forma rígida

using System.Text;
using System.Security.Cryptography;

class ExampleClass
{
    public void ExampleMethod(byte[] someOtherBytesForIV)
    {
        byte[] key = Encoding.ASCII.GetBytes("AAAAAaazaoensuth");
        SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
        rijn.CreateEncryptor(key, someOtherBytesForIV);
    }
}

Solución

using System.Text;
using System.Security.Cryptography;

class ExampleClass
{
    public void ExampleMethod(char[] chars, byte[] someOtherBytesForIV)
    {
        byte[] key = Encoding.ASCII.GetBytes(chars);
        SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
        rijn.CreateEncryptor(key, someOtherBytesForIV);
    }
}