visual versión una tengo superior studio saber referencia que proyecto net misma los instalar instalada framework existente está este equipo ensamblados encuentran destino como change cambiar c# xml encryption x509certificate2 encryption-asymmetric

c# - una - no se encuentran los ensamblados de referencia de la versión de.net framework



Error en el método EncryptXml DecryptDocument después de la actualización de.NET Framework (3)

Hay algunos cambios de tiempo de ejecución en .Net 4.6.2 que afectan a EncrtyptedXml - ver https://msdn.microsoft.com/en-us/library/mt670901(v=vs.110).aspx#Anchor_5

Tengo una función antigua escrita en 2013 que descifra xml cifrada por otro programa.

El código es realmente simple

public static void Decrypt(XmlDocument Doc) { // Check the arguments. if (Doc == null) throw new ArgumentNullException("Doc"); // Create a new EncryptedXml object. EncryptedXml exml = new EncryptedXml(Doc); // Decrypt the XML document. exml.DecryptDocument(); }

Funcionó hasta hace poco que algunos de nuestros clientes comenzaron a actualizar su marco de trabajo a 4.6.2, por lo que el método DecryptDocument () dejó de funcionar. Ahora arroja una excepción "El grupo de algoritmo" no es válido ". Si elimino .net framework 4.6.2, funciona de nuevo.

El código de muestra en este enlace reproducirá el error, encriptará con éxito y luego no podrá descifrar.

Estoy usando certificados A3, token pendrive. ¿Alguien se ha enfrentado a este problema? hay algún trabajo en .net 4.6.2?

Editar 1:

Stacktrace:

at System.Security.Cryptography.CngAlgorithmGroup..ctor(String algorithmGroup) at System.Security.Cryptography.CngKey.get_AlgorithmGroup() at System.Security.Cryptography.RSACng..ctor(CngKey key) at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate) at System.Security.Cryptography.CngLightup.GetRSAPrivateKey(X509Certificate2 cert) at System.Security.Cryptography.Xml.EncryptedXml.DecryptEncryptedKey(EncryptedKey encryptedKey) at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri) at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument() at Criptografar.Program.Decrypt(XmlDocument Doc) in C:/Users/leoka/Documents/Visual Studio 2017/Projects/ConsoleApp4/Criptografar/Program.cs:line 152 at Criptografar.Program.Main(String[] args) in C:/Users/leoka/Documents/Visual Studio 2017/Projects/ConsoleApp4/Criptografar/Program.cs:line 83


Me encontré con algo muy similar hoy que resultó ser un error en .NET 4.6.2: https://github.com/Microsoft/dotnet/issues/341

De acuerdo con este problema, hay dos soluciones:

1) Actualización del sistema operativo a Windows Server 2012R2 o posterior, 2) cargando el perfil de usuario.


No puedo reproducir el problema yo mismo, no tengo el "token pendrive", que sospecho que es el problema, así que esto es conjetura. Hay dos generaciones de API criptográficas en Windows: la "antigua" y la "nueva generación", conocida como CNG . Ahora, si nos fijamos en el código fuente del tipo CngLightup que aparece a medio camino de su rastro de pila, específicamente el método DetectRsaCngSupport , verá que .NET framework intenta usar la API de nueva generación si es posible. Supongo que el dispositivo "pendrive token" no es compatible con la nueva API. Puede verificar esto forzando el uso de la antigua API. Desafortunadamente, no parece haber una bandera de configuración pública que controle esto, por lo que debe recurrir a los hacks basados ​​en la reflexión. Por ejemplo, puede poner algo como esto al comienzo de su programa, para que se ejecute una vez, antes de intentar la operación de descifrado:

var cngLightupType = typeof(EncryptedXml).Assembly.GetType("System.Security.Cryptography.CngLightup"); var preferRsaCngField = cngLightupType.GetField("s_preferRsaCng", BindingFlags.Static | BindingFlags.NonPublic); var getRsaPublicKeyField = cngLightupType.GetField("s_getRsaPublicKey", BindingFlags.Static | BindingFlags.NonPublic); var getRsaPrivateKeyField = cngLightupType.GetField("s_getRsaPrivateKey", BindingFlags.Static | BindingFlags.NonPublic); preferRsaCngField.SetValue(null, new Lazy<bool>(() => false)); getRsaPublicKeyField.SetValue(null, null); getRsaPrivateKeyField.SetValue(null, null);

Tenga en cuenta que es extremadamente hacky, no es seguro para subprocesos, se omite el manejo de errores, etc. Si verifica que el uso de GNC es el problema, puede solicitar al proveedor "token pendrive" que proporcione controladores que funcionen con GNC. O puedes vivir con el truco anterior, reescrito para mayor seguridad.