2016-06-29 1 views
0

J'ai un très ancien code VB6 qui est utilisé pour générer le hachage du mot de passe. Le code utilise la fonction CryptAcquireContext avec advapi32.dll pour générer le hachage. Il y a tellement de code avec des variables ayant des valeurs hexadécimales etc. Le code prendra une éternité à migrer vers ASP.NET.Convertir le code CryptAcquireContext VB6 en ASP.NET

Nous avons beaucoup de données chiffrées à l'aide de ce code Hash et nous n'avons aucun moyen de le décrypter en texte brut.

J'ai besoin d'écrire du code similaire dans ASP.NET C# qui génère le même hachage que le code VB6.

Exemple: Regardez l'image ci-dessous sur la façon dont il génère HASH de texte brut:

enter image description here

travail de code C# sous des formes Windows uniquement à l'exception que CryptAcquireContext retourne false lorsque le programme est exécuté deuxième fois:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Security; 
using System.Web; 
using System.Security.Cryptography; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace CryptoGraphicHash 
{ 
    public partial class Form1 : Form 
    { 
     static uint CRYPT_NEWKEYSET = 0x8; 

     static uint CRYPT_MACHINE_KEYSET = 0x20; 

     static uint ALG_CLASS_HASH = 32768; 
     // Algorithm types 
     static uint ALG_TYPE_ANY = 0; 

     static uint PROV_RSA_FULL = 1; 
     static uint ALG_SID_SHA = 4; 

     static string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0"; 
     static uint CALG_SHA = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_SHA; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      var test = GenerateHash(textBox1.Text); 
      textBox2.Text = test; 
     } 

     private string GenerateHash(string plaintext) 
     {    
      string sContainer = string.Empty; 
      string sProvider = MS_DEF_PROV; 

      IntPtr hProv = new IntPtr(); 
      IntPtr hKey = new IntPtr(0); 
      IntPtr phHash = new IntPtr(); 

      try 
      { 
       bool res = Crypt32.CryptAcquireContext(out hProv, sContainer, sProvider, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET); 
       if (!res) 
       { 
        bool res1 = Crypt32.CryptAcquireContext(out hProv, sContainer, sProvider, PROV_RSA_FULL, CRYPT_NEWKEYSET); 
        if (!res1) 
        { 
         MessageBox.Show("CryptAcquireContext is false for second time so exiting the hash."); 
         var error = Marshal.GetLastWin32Error(); 
         Win32Exception test = new Win32Exception(error); 
         MessageBox.Show("Last Win32 error code: " + error); 
         MessageBox.Show("Last Win32 error msg: " + test.Message); 
         return string.Empty; 
        } 
       } 
       MessageBox.Show("hProv handle value is: " + hProv.ToString()); 
       //Once we have received the context, next we create hash object     
       bool hashCreateResponse = Crypt32.CryptCreateHash(hProv, CALG_SHA, hKey, 0, ref phHash); 
       if (!hashCreateResponse) 
       { 
        MessageBox.Show("CryptCreateHash is false so exiting with last win32 error: " + Marshal.GetLastWin32Error()); 
        return string.Empty; 
       } 
       //Hash the data 
       byte[] pbData = Encoding.ASCII.GetBytes(plaintext); 
       bool hashDataResponse = Crypt32.CryptHashData(phHash, pbData, (uint)plaintext.Length, 0); 
       if (!hashDataResponse) 
       { 
        MessageBox.Show("CryptHashData is false so exiting."); 
        return string.Empty; 
       } 
       uint paramLen = 0; 
       byte[] paramValue = new byte[0]; 

       bool getHashParamResponse = Crypt32.CryptGetHashParam(phHash, 0x0002, paramValue, ref paramLen, 0); 

       if (234 == Marshal.GetLastWin32Error()) 
       { 
        paramValue = new byte[paramLen]; 
        bool getHashParamResponse1 = Crypt32.CryptGetHashParam(phHash, 0x0002, paramValue, ref paramLen, 0); 
       } 

       //destroy the key 
       Crypt32.CryptDestroyKey(hKey); 

       //Destroy the hash object 
       Crypt32.CryptDestroyHash(phHash); 

       //Release provider handle 
       Crypt32.CryptReleaseContext(hProv, 0); 
       var sb = new StringBuilder(); 
       foreach(var item in paramValue) 
       { 
        sb.Append(Microsoft.VisualBasic.Strings.Chr(item)); 
       } 
       return sb.ToString(); 
      } 
      catch(Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
       MessageBox.Show(ex.InnerException.StackTrace); 
       throw ex; 
      } 
     } 
    } 


    public class Crypt32 
    { 
     public enum HashParameters 
     { 
      HP_ALGID = 0x0001, // Hash algorithm 
      HP_HASHVAL = 0x2, // Hash value 
      HP_HASHSIZE = 0x0004 // Hash value size 
     } 

     [DllImport("advapi32.dll", SetLastError = true)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     public static extern bool CryptAcquireContext(
out IntPtr phProv, 
string pszContainer, 
string pszProvider, 
uint dwProvType, 
uint dwFlags); 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern bool CryptCreateHash(IntPtr hProv, uint algId, IntPtr hKey, uint dwFlags, ref IntPtr phHash); 

     [DllImport("advapi32.dll", SetLastError = true)] 
     public static extern bool CryptDestroyHash(IntPtr hHash);   

     [DllImport("advapi32.dll", SetLastError = true)] 
     public static extern bool CryptDestroyKey(IntPtr phKey); 

     [DllImport("advapi32.dll", SetLastError = true)] 
     public static extern bool CryptHashData(IntPtr hHash, byte[] pbData, uint dataLen, uint flags); 

     [DllImport("Advapi32.dll", EntryPoint = "CryptReleaseContext", CharSet = CharSet.Unicode, SetLastError = true)] 
     public static extern bool CryptReleaseContext(IntPtr hProv,Int32 dwFlags); 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern bool CryptGetHashParam(IntPtr hHash, 
     uint dwParam, 
     Byte[] pbData, 
     ref uint pdwDataLen, 
     uint dwFlags); 
     //public static extern bool CryptGetHashParam(IntPtr hHash, uint dwParam, [Out] byte[] pbData, [In, Out] uint pdwDataLen, uint dwFlags); 
    } 
} 

Répondre

2

Vous pouvez envisager d'utiliser la plate-forme services (Invoke PInvoke) pour appeler advapi32.dll fonctions de .NET. Cela pourrait accélérer le processus de migration.

Vous pouvez trouver des signatures sur http://pinvoke.net

+0

Merci beaucoup pour la suggestion. J'ai un code de travail maintenant mais le problème est que, le CryptAcquireContext est vrai seulement pour la première fois quand j'exécute le programme. Les appels suivants au programme renvoie false à CryptAcquireContext. Pouvez-vous s'il vous plaît me montrer où je peux faire quelque chose de mal? – user2272865

+0

Avez-vous regardé le code d'erreur renvoyé par GetLastError lorsque CryptAcquireContext renvoie false? – Joe

+0

En fait, j'ai corrigé l'erreur en changeant le dernier paramètre de la fonction CryptAcquireContext à 0. On dirait que cela fonctionne bien maintenant. – user2272865

0

Donc finalement avec l'aide de la suggestion de Joe, la documentation PInvoke et quelques modifications de code trouvés sur la pile sur le flux, j'ai pu créer une fenêtre de travail avec succès formulaire de demande qui a 2 zones de texte et un bouton. Entrez le texte en clair dans la première zone de texte et cliquez sur le bouton pour obtenir la valeur de hachage dans la deuxième zone de texte. Le code complet est:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Security; 
using System.Web; 
using System.Security.Cryptography; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace CryptoGraphicHash 
{ 
    public partial class Form1 : Form 
    { 
     static uint CRYPT_NEWKEYSET = 0x8; 

     static uint CRYPT_MACHINE_KEYSET = 0x20; 

     static uint ALG_CLASS_HASH = 32768; 
     // Algorithm types 
     static uint ALG_TYPE_ANY = 0; 

     static uint PROV_RSA_FULL = 1; 
     static uint ALG_SID_SHA = 4; 

     static string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0"; 
     static uint CALG_SHA = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_SHA; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      var test = GenerateHash(textBox1.Text); 
      textBox2.Text = test; 
     } 

     private void HandleWin32Error() 
     { 
      var error = Marshal.GetLastWin32Error(); 
      Win32Exception ex = new Win32Exception(error); 
      MessageBox.Show("Last Win32 error code: " + error); 
      MessageBox.Show("Last Win32 error msg: " + ex.Message); 
     } 

     private string GenerateHash(string plaintext) 
     {    
      string sContainer = string.Empty; 
      string sProvider = MS_DEF_PROV; 

      IntPtr hProv = new IntPtr(); 
      IntPtr hKey = new IntPtr(0); 
      IntPtr phHash = new IntPtr(); 

      try 
      { 
       bool res = Crypt32.CryptAcquireContext(out hProv, sContainer, sProvider, PROV_RSA_FULL, 0); 
       if (!res) 
       { 
        MessageBox.Show("CryptAcquireContext is false for first time so will try again with CRYPT_NEWKEYSET."); 
        HandleWin32Error(); 
        bool res1 = Crypt32.CryptAcquireContext(out hProv, sContainer, sProvider, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET + CRYPT_NEWKEYSET); 
        if (!res1) 
        { 
         MessageBox.Show("CryptAcquireContext is false for second time so exiting the hash."); 
         HandleWin32Error(); 
         return string.Empty; 
        } 
       } 
       MessageBox.Show("hProv handle value is: " + hProv.ToString()); 
       //Once we have received the context, next we create hash object     
       bool hashCreateResponse = Crypt32.CryptCreateHash(hProv, CALG_SHA, hKey, 0, ref phHash); 
       if (!hashCreateResponse) 
       { 
        MessageBox.Show("CryptCreateHash is false so exiting with last win32 error: " + Marshal.GetLastWin32Error()); 
        return string.Empty; 
       } 
       //Hash the data 
       byte[] pbData = Encoding.ASCII.GetBytes(plaintext); 
       bool hashDataResponse = Crypt32.CryptHashData(phHash, pbData, (uint)plaintext.Length, 0); 
       if (!hashDataResponse) 
       { 
        MessageBox.Show("CryptHashData is false so exiting."); 
        return string.Empty; 
       } 
       uint paramLen = 0; 
       byte[] paramValue = new byte[0]; 

       bool getHashParamResponse = Crypt32.CryptGetHashParam(phHash, 0x0002, paramValue, ref paramLen, 0); 

       if (234 == Marshal.GetLastWin32Error()) 
       { 
        paramValue = new byte[paramLen]; 
        bool getHashParamResponse1 = Crypt32.CryptGetHashParam(phHash, 0x0002, paramValue, ref paramLen, 0); 
       } 

       //destroy the key 
       Crypt32.CryptDestroyKey(hKey); 

       //Destroy the hash object 
       Crypt32.CryptDestroyHash(phHash); 

       //Release provider handle 
       Crypt32.CryptReleaseContext(hProv, 0); 
       var sb = new StringBuilder(); 
       foreach(var item in paramValue) 
       { 
        sb.Append(Microsoft.VisualBasic.Strings.Chr(item)); 
       } 
       return sb.ToString(); 
      } 
      catch(Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
       MessageBox.Show(ex.InnerException.StackTrace); 
       throw ex; 
      } 
     } 
    } 


    public class Crypt32 
    { 
     public enum HashParameters 
     { 
      HP_ALGID = 0x0001, // Hash algorithm 
      HP_HASHVAL = 0x2, // Hash value 
      HP_HASHSIZE = 0x0004 // Hash value size 
     } 

     [DllImport("advapi32.dll", SetLastError = true)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     public static extern bool CryptAcquireContext(
out IntPtr phProv, 
string pszContainer, 
string pszProvider, 
uint dwProvType, 
uint dwFlags); 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern bool CryptCreateHash(IntPtr hProv, uint algId, IntPtr hKey, uint dwFlags, ref IntPtr phHash); 

     [DllImport("advapi32.dll", SetLastError = true)] 
     public static extern bool CryptDestroyHash(IntPtr hHash);   

     [DllImport("advapi32.dll", SetLastError = true)] 
     public static extern bool CryptDestroyKey(IntPtr phKey); 

     [DllImport("advapi32.dll", SetLastError = true)] 
     public static extern bool CryptHashData(IntPtr hHash, byte[] pbData, uint dataLen, uint flags); 

     [DllImport("Advapi32.dll", EntryPoint = "CryptReleaseContext", CharSet = CharSet.Unicode, SetLastError = true)] 
     public static extern bool CryptReleaseContext(IntPtr hProv,Int32 dwFlags); 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     public static extern bool CryptGetHashParam(IntPtr hHash, 
     uint dwParam, 
     Byte[] pbData, 
     ref uint pdwDataLen, 
     uint dwFlags); 
     //public static extern bool CryptGetHashParam(IntPtr hHash, uint dwParam, [Out] byte[] pbData, [In, Out] uint pdwDataLen, uint dwFlags); 
    } 
}