2016-06-29 2 views
0

암호 용 해시를 생성하는 데 사용되는 매우 오래된 VB6 코드가 있습니다. 이 코드는 advapi32.dll과 함께 CryptAcquireContext 함수를 사용하여 해시를 생성합니다. 16 진수 값 등을 갖는 변수에는 많은 코드가 있습니다.이 코드는 영원히 ASP.NET으로 마이그레이션하는 데 오래 걸릴 것입니다.CryptAcquireContext VB6 코드를 ASP.NET으로 변환

우리는이 해시 코드를 사용하여 암호화 된 많은 데이터가 있으며 일반 텍스트로 다시 해독 할 방법이 없습니다.

ASP.NET C#에서 VB6 코드와 동일한 해시를 생성하는 비슷한 코드를 작성해야합니다.

예 : 그것은 일반 텍스트에서 해시를 생성하는 방법에 아래 그림을 봐 :

enter image description here

작업 C# 코드 Windows에서 프로그램을 두 번 실행하면 CryptAcquireContext가 false를 반환하는 유일한 예외와 양식 :

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); 
    } 
} 

답변

2

당신은 .NET에서 advapi32.dll의 함수를 호출하는 플랫폼 호출 서비스 (PInvoke를)를 사용하는 것이 좋습니다. 이렇게하면 마이그레이션 프로세스가 빨라질 수 있습니다.

당신은 조의 제안의 도움으로, PInvoke를 문서와 흐름을 스택에서 발견 된 일부 코드 비틀기와 그래서 결국 http://pinvoke.net

+0

제안 해 주셔서 감사합니다. 지금 작동하는 코드가 있지만 문제는 CryptAcquireContext가 프로그램을 실행할 때 처음으로 참 인 것입니다. 이후의 프로그램 호출은 CryptAcquireContext에서 false를 반환합니다. 내가 잘못하고있는 부분을 지적 해 주시겠습니까? – user2272865

+0

CryptAcquireContext가 false를 반환 할 때 GetLastError가 반환하는 오류 코드를 살펴 보셨습니까? – Joe

+0

실제로 CryptAcquireContext 함수의 마지막 매개 변수를 0으로 변경하여 오류를 수정했습니다. 이제 제대로 작동하는 것 같습니다. – user2272865

0

에 서명을 찾을 수 있습니다, 나는 형성이 텍스트 상자를 가지고 응용 프로그램을 성공적으로 작업 창을 만들 수 있었고 단추. 첫 번째 텍스트 상자에 일반 텍스트를 입력하고 버튼을 클릭하여 두 번째 텍스트 상자에 해시 값을 가져옵니다. 전체 코드는 다음과 같습니다.

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); 
    } 
}