2010-03-30 20 views
5

que es tarde, estoy cansado, y probablemente ser bastante denso ....Asegurar una clave de licencia de claves RSA con

He escrito una aplicación que necesito para asegurar por lo que sólo se ejecutará en máquinas que me generar una clave para. Lo que estoy haciendo por ahora es obtener el número de serie de la BIOS y generar un hash a partir de eso, luego estoy encriptando usando una clave privada XML RSA. Luego firmo el XML para asegurarme de que no se manipule. Estoy tratando de empaquetar la clave pública para descifrar y verificar la firma con, pero cada vez que intento ejecutar el código como un usuario diferente al que generó la firma obtengo un error en la firma.

La mayor parte de mi código ha sido modificado a partir del código de muestra que he encontrado, ya que no estoy tan familiarizado con el cifrado RSA como me gustaría. Debajo está el código que estaba usando y el código que pensé que necesitaba usar para que esto funcionara bien ...

Cualquier comentario sería muy apreciado ya que estoy perdido en este punto el código original con el que estaba trabajando fue esta, este código funciona bien siempre y cuando el usuario lanzar el programa es el mismo que firmó el documento originalmente ...

CspParameters cspParams = new CspParameters(); 
      cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"; 
      cspParams.Flags = CspProviderFlags.UseMachineKeyStore; 

      // Create a new RSA signing key and save it in the container. 
      RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams) 
      { 
       PersistKeyInCsp = true, 
      }; 

este código es lo que yo creo que debería estar haciendo, pero está fallando para verificar la firma sin importar lo que hago, independientemente de si es el mismo usuario o uno diferente ...

RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(); 
      //Load the private key from xml file 
      XmlDocument xmlPrivateKey = new XmlDocument(); 
      xmlPrivateKey.Load("KeyPriv.xml"); 
      rsaKey.FromXmlString(xmlPrivateKey.InnerXml); 

Creo que esto tiene algo que ver con el nombre del contenedor de claves (Ser un tonto real aquí, discúlpeme) Estoy bastante seguro de que esta es la línea que está causando que funcione en el primer caso y evitando que trabajando en el segundo caso ....

cspParams.KeyContainerName = "XML_DSIG_RSA_KEY"; 

¿existe una manera para que firme/cifrar el XML con una clave privada cuando se genera la solicitud de licencia y luego dejar caer la clave pública en el directorio de la aplicación y el uso que para verificar/descifrar el código? Puedo soltar la parte de encriptación si puedo conseguir que la parte de la firma funcione correctamente. Lo estaba usando como una copia de seguridad para ocultar el origen del código de licencia del que estoy filtrando.

¿Tiene algo de esto sentido? ¿Soy un tonto total?

Gracias por cualquier ayuda alguien me puede dar en este ..

Respuesta

5

he utilizado este método para firmar documentos XML utilizando una clave privada almacenada en un archivo XML que entonces integrado en el .dll aplicación como un recurso. Creo que puede tener problemas con los permisos para acceder al almacén de claves, y esto también crearía problemas al transferir el código a otros servidores, etc.

Aquí está el código para obtener la clave privada como un recurso incrustado y firmar el documento: (signo es el nombre de la clase este método se encuentra en, Licensing.Private.Private.xml es una combinación del nombre por defecto + carpeta + nombre de archivo del recurso)

public static void SignDocument(XmlDocument xmldoc) 
{ 
    //Get the XML content from the embedded XML privatekey. 
    Stream s = null; 
    string xmlkey = string.Empty; 
    try 
    { 
     s = typeof(Sign).Assembly.GetManifestResourceStream("Licensing.Private.Private.xml"); 

     // Read-in the XML content. 
     StreamReader reader = new StreamReader(s); 
     xmlkey = reader.ReadToEnd(); 
     reader.Close(); 
    } 
    catch (Exception e) 
    { 
     throw new Exception("Error: could not import key:",e); 
    } 

    // Create an RSA crypto service provider from the embedded 
    // XML document resource (the private key). 
    RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
    csp.FromXmlString(xmlkey); 
    //Creating the XML signing object. 
    SignedXml sxml = new SignedXml(xmldoc); 
    sxml.SigningKey = csp; 

    //Set the canonicalization method for the document. 
    sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl; // No comments. 

    //Create an empty reference (not enveloped) for the XPath transformation. 
    Reference r = new Reference(""); 

    //Create the XPath transform and add it to the reference list. 
    r.AddTransform(new XmlDsigEnvelopedSignatureTransform(false)); 

    //Add the reference to the SignedXml object. 
    sxml.AddReference(r); 

    //Compute the signature. 
    sxml.ComputeSignature(); 

    // Get the signature XML and add it to the document element. 
    XmlElement sig = sxml.GetXml(); 
    xmldoc.DocumentElement.AppendChild(sig); 
} 

Utilice el siguiente código al generar el privado Claves .xml y public.xml Mantenga el archivo privado.xml seguro, obviamente.

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); 
File.WriteAllText(@"C:\privateKey.xml", rsa.ToXmlString(true)); // Private Key 
File.WriteAllText(@"C:\publicKey.xml", rsa.ToXmlString(false)); // Public Key 
+0

¡Impresionante! ¡Gracias por la ayuda! Esto no solo solucionó el problema de mi licencia sino que también me ayudó a administrar otros recursos en mi aplicación. –

+0

Acabo de darme cuenta de que no me estoy deshaciendo del StreamReader allí en un final en el bloque try catch ... –

0

Guess, el problema es que los diferentes usuarios no tienen acceso a la clave que se almacena para la primera usuario (Tenga en cuenta: No soy un experto en criptografía).

Cuestiones relacionadas