2011-09-15 239 views
12

Aquí está mi código.Por qué estoy obteniendo la excepción "Algoritmo inválido especificado"

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password"); 
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey; 
string id = CryptoConfig.MapNameToOID("SHA256"); 
return csp.SignData(File.ReadAllBytes(filePath), id); 

En la última línea que estoy recibiendo la excepción:

System.Security.Cryptography.CryptographicException "algoritmo especificado no es válido."

¿Qué estoy haciendo mal?

ACTUALIZACIÓN:

id = 2.16.840.1.101.3.4.2.1

+0

¿Cuál es el valor de 'id'? – dtb

+0

Actualicé la pregunta con el valor de id. – scott

Respuesta

9

No hay ningún problema con el código de .NET o el código de CSP que ya ha proporcionado.

Su problema es que la CSP simplemente no es compatible con SHA 256. Puede obtener más información here

+0

¿Hay alguna forma de que esto funcione? Estoy portando esto desde Java y necesita usar los mismos algoritmos. Por lo que puedo decir, está usando rsa + sha – scott

+0

Es posible que desee comprobar http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256.aspx que es una clase SHA256 en. NET Framework. Pero, no lo he usado. –

+0

SHA256CryptoServiceProvider no acepta una clave asimétrica – scott

2

Nota que utilizo SHA512 pero SHA256 a trabajar con los siguientes ejemplos:

"algoritmo no válido" Me tomó una eternidad descubrirlo e intenté prácticamente todo. Apoyos a Gonzalo Gallotti por publicar el enlace al código que me ayudó. Comenté mi código para mostrar lo que está haciendo cada paso. NOTA: este código no funcionará correctamente sin un certificado generado que se publica a continuación el ejemplo de código:

 public void GetCertificate() { 

     // Get the Machine Cert Store 
     var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 

     string alg = CryptoConfig.MapNameToOID("SHA512"); 

     // Open the cert store 
     store.Open(OpenFlags.ReadWrite); 

     // Loop through each certificate within the store 
     foreach (X509Certificate2 myCert in store.Certificates) 
     { 
      // Get the certificate we are looking for 
      if (myCert.IssuerName.Name.Contains("CN=YourSite")) 
      { 
       // Check if the certificate has a private key 
       if (myCert.HasPrivateKey) 
       { 
        // Get your custom signature as a string 
        string mySignature = GetSignatureString(); 

        // Convert signature to byte array 
        byte[] originalData = Encoding.UTF8.GetBytes(mySignature); 

        // Create RSA provider from private key 
        RSACryptoServiceProvider rsaProvider = (RSACryptoServiceProvider)myCert.PrivateKey; 

        // Sign the signature with SHA512 
        byte[] signedSignature = signedSignature = rsaProvider.SignData(originalData, alg); 

        if (rsaProvider.VerifyData(originalData, alg, signedSignature)) 
        { 
         // Signature is verified Do Stuff 
        } 
        else 
        { 
         throw new Exception("The data does not match the signature."); 
        } 
       } 
      } 
     } 
    } 

Siguiente - el certificado tiene que ser SHA512 y utilizar un (Proveedor de servicios de cifrado) CSP que es capaz SHA512. Aquí hay una lista de CSP y sus capacidades. Si busca SHA512, encontrará el "Microsoft Enhanced RSA and AES Cryptographic Provider". Por defecto, la generación de certificados no utiliza esto (al menos en Windows) por lo que debe especificarlo cuando crea el certificado.

Crear clave privada y el certificado - este paso le hará preguntas, estado, región, etc, etc

openssl req -x509 -nodes -sha512 -newkey rsa:2048 -keyout 512key.pem -out 512cert.pem -days 3650 

Crear archivo PFX a importar en su almacén de certificados mediante el proveedor RSA y AES de cifrado mejorado de Microsoft:

openssl pkcs12 –export –in 512cert.pem –inkey 512key.pem –CSP “Microsoft Enhanced RSA and AES Cryptographic Provider” –out 512pfx.pfx 
+0

No estoy seguro de qué fue el voto negativo sobre esto. Sin duda me ayudó, ¡muchas gracias! +1 +1 –

1

Tiene un problema similar pero lo resolvió. Si no está utilizando X509 sino simplemente RSACryptoServiceProvider para obtener las claves, solo se admite SHA1.

Cuestiones relacionadas