2010-02-04 50 views
6

Estoy tratando de enviar algunos datos cifrados de mi sitio de SharePoint al sitio de PeopleSoft de mi empresa. La gente de PeopleSoft insiste en que tengo que usar la biblioteca OpenSSL para mi cifrado. He descargado e instalado el proyecto OpenSSL.Net de SourceForge.¿Cómo uso el contenedor OpenSSL.Net C# para encriptar una cadena con AES?

Para mis propósitos, simplemente necesito encriptar una cadena con AES. Sé cómo hacer esto con la biblioteca System.Security.Cryptography, pero estoy teniendo un momento muy difícil traducir esto al lado de OpenSSL.Net. ¡Muy frustrante, ya que puedo ver todo lo que creo que necesito en Intellisense!

¿Alguien tiene un ejemplo de cifrado/descifrado de cadenas con AES utilizando el contenedor OpenSSL.Net?

Gracias!

-Nick

Respuesta

4

Aquí está la muestra que funciona para mí. Lo simplifiqué usando copiar y pegar, pero no debería importar.

Estoy usando la contraseña de texto debido a la compatibilidad con la biblioteca JS, pero SSL abierto admite el uso directo de byte [] Key y IV, por lo que depende de usted qué usar.

Con el fin de cambiar los datos binarios en la cadena sólo tiene que utilizar

Encoding.UTF8.GetBytes() and Encoding.UTF8.GetString() 

para convertir de ida y vuelta.

public Byte[] Encrypt(Byte[] data, String password) 
    { 
     //Just random 8 bytes for salt 
     var salt = new Byte[] {1, 2, 3, 4, 5, 6, 7, 8}; 

     using (var cc = new CipherContext(Cipher.AES_256_CBC)) 
     { 
      //Constructing key and init vector from string password 
      byte[] passwordBytes = Encoding.UTF8.GetBytes(password); 
      byte[] iv; 
      byte[] key = cc.BytesToKey(MessageDigest.MD5, salt, passwordBytes, 1, out iv); 

      var memoryStream = new MemoryStream(); 

      //Performing encryption thru unmanaged wrapper 
      var aesData = cc.Crypt(data, key, iv, true); 

      //Append salt so final data will look Salted___SALT|RESTOFTHEDATA 
      memoryStream.Write(Encoding.UTF8.GetBytes("Salted__"), 0, 8); 
      memoryStream.Write(salt, 0, 8); 
      memoryStream.Write(aesData, 0, aesData.Length); 

      return memoryStream.ToArray(); 
     } 
    } 

    public Byte[] Decrypt(String password, Byte[] encryptedData) 
    { 
     byte[] salt = null; 
     //extracting salt if presented 
     if (encryptedData.Length > 16) 
     { 
      if (Encoding.UTF8.GetString(encryptedData).StartsWith("Salted__")) 
      { 
       salt = new Byte[8]; 
       Buffer.BlockCopy(encryptedData, 8, salt, 0, 8); 
      } 
     } 

     //Removing salt from the original array 
     int aesDataLength = encryptedData.Length - 16; 
     byte[] aesData = new byte[aesDataLength]; 
     Buffer.BlockCopy(encryptedData, 16, aesData, 0, aesDataLength); 


     using (var cc = new CipherContext(Cipher.AES_256_CBC)) 
     { 
      //Constructing key and init vector from string password and salt 
      byte[] passwordBytes = Encoding.UTF8.GetBytes(password); 
      byte[] iv; 
      byte[] key = cc.BytesToKey(MessageDigest.MD5, salt, passwordBytes, 1, out iv); 

      //Decrypting 
      return cc.Decrypt(aesData, key, iv, 0); 

     } 


    } 
+1

Esos son algunos altamente ocho bytes aleatorios para la sal;) – Nate

+0

Bueno, lo suficientemente aleatoria para responder a la pregunta, ya que de hecho no es un código vivo :) –

+0

Mi aplicación se basa fuera de este ejemplo. Estoy usando el contexto Cipher.AES_256_CBC, pero si mi contraseña es <16 bytes cuando se llama a cc.Crypt arroja una excepción. Porque está tratando de escribir los datos cifrados que son 16 bytes en el búfer de 8 bytes que crea. ¿Encontraste esto? Estoy usando OpenSSL.Net 0.4.4 y estoy usando un resumen de mensaje SHA1. – Jeff

Cuestiones relacionadas