using Muchinfo.MTPClient.CustomException; using Muchinfo.MTPClient.Resources; using System; using System.Runtime.InteropServices; using System.Text; namespace Muchinfo.MTPClient.Infrastructure.Helpers { public class EncryptHelper { [DllImport("crypto.dll", EntryPoint = "MIGetSafeHandle", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern long MIGetSafeHandle(); [DllImport("crypto.dll", EntryPoint = "MIFreeSafeHandle", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern void MIFreeSafeHandle(long pSafeHandle); [DllImport("crypto.dll", EntryPoint = "MILoad", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MILoad(IntPtr pDst, int iDst, long pSafeHandle); [DllImport("crypto.dll", EntryPoint = "MITransEncrypt", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MITransEncrypt(IntPtr pDst, int iDst, IntPtr pSrc, int iSrc, long pSafeHandle); [DllImport("crypto.dll", EntryPoint = "MIGetEncryptDataLen", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MIGetEncryptDataLen(ref int iRevLen, IntPtr pData, int iLen, long pSafeHandle); [DllImport("crypto.dll", EntryPoint = "MITransDecrypt", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MITransDecrypt(IntPtr pDst, int iDst, IntPtr pSrc, int iSrc, long pSafeHandle); [DllImport("crypto.dll", EntryPoint = "MIGetDecryptDataLen", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MIGetDecryptDataLen(ref int iRevLen, IntPtr pData, int iLen, long pSafeHandle); // _DLL_EXP_API int32_t MIGetDecryptDataLen(int32_t &iRevLen, const char *pData, int32_t iLen, intptr_t pSafeHandle); [DllImport("crypto.dll", EntryPoint = "MIMD5Encrypt", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MIMD5Encrypt(IntPtr pDst, ref int iDst, IntPtr pSrc, int iSrc); [DllImport("crypto.dll", EntryPoint = "MIMD5GetEncryptDataLen", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MIMD5GetEncryptDataLen(ref int iRevLen, IntPtr pData, int iLen); [DllImport("crypto.dll", EntryPoint = "MIAlterTransPwd", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MIAlterTransPwd(StringBuilder pPwd, long pSafeHandle); [DllImport("crypto.dll", EntryPoint = "MISHA256Encrypt", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MISHA256Encrypt(IntPtr pDst, ref int iDst, IntPtr pSrc, int iSrc); [DllImport("crypto.dll", EntryPoint = "MISHA256GetEncryptDataLen", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int MISHA256GetEncryptDataLen(ref int iRevLen, IntPtr pData, int iLen); /// /// SHA256加密 /// /// The source. /// System.String. public static string SHA256(string source) { byte[] szOutData = null; var szInData = Encoding.UTF8.GetBytes(source); int iResult = 0; ////加密后的数据长度 int iOutEncryptDataLen = 0; ////待加密数据长度 int iInEncryptDataLen = szInData.Length; ////申请内存拷贝待加密数据 IntPtr pInEncryptData = Marshal.AllocHGlobal(iInEncryptDataLen); Marshal.Copy(szInData, 0, pInEncryptData, iInEncryptDataLen); // 获取加密后内存的长度 iResult = MISHA256GetEncryptDataLen(ref iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen); if (0 == iResult) { ////创建内存 IntPtr pOutEncryptData = Marshal.AllocHGlobal(iOutEncryptDataLen); ////加密 iResult = MISHA256Encrypt(pOutEncryptData, ref iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen); if (iResult == 0) { ////拷贝到数组上面 szOutData = new byte[iOutEncryptDataLen]; Marshal.Copy(pOutEncryptData, szOutData, 0, iOutEncryptDataLen); } ////释放内存 Marshal.FreeHGlobal(pOutEncryptData); } ////释放内存 Marshal.FreeHGlobal(pInEncryptData); if (szOutData == null) { return null; } // return Encoding.UTF8.GetString(szOutData); return Encoding.UTF8.GetString(szOutData, 0, 64); } /// /// SHA256加密 /// /// The source. /// System.String. public static string MD5(string source) { byte[] szOutData = null; var szInData = Encoding.UTF8.GetBytes(source); int iResult = 0; ////加密后的数据长度 int iOutEncryptDataLen = 0; ////待加密数据长度 int iInEncryptDataLen = szInData.Length; ////申请内存拷贝待加密数据 IntPtr pInEncryptData = Marshal.AllocHGlobal(iInEncryptDataLen); Marshal.Copy(szInData, 0, pInEncryptData, iInEncryptDataLen); // 获取加密后内存的长度 iResult = MIMD5GetEncryptDataLen(ref iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen); if (0 == iResult) { ////创建内存 IntPtr pOutEncryptData = Marshal.AllocHGlobal(iOutEncryptDataLen); ////加密 iResult = MIMD5Encrypt(pOutEncryptData, ref iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen); if (iResult == 0) { ////拷贝到数组上面 szOutData = new byte[iOutEncryptDataLen]; Marshal.Copy(pOutEncryptData, szOutData, 0, iOutEncryptDataLen); } ////释放内存 Marshal.FreeHGlobal(pOutEncryptData); } ////释放内存 Marshal.FreeHGlobal(pInEncryptData); if (szOutData == null) { return null; } return Encoding.UTF8.GetString(szOutData); } private readonly long pSafeHandle; /// /// Initializes a new instance of the class. /// public EncryptHelper() { int iResult = 0; int iLoadTemp = 0; IntPtr pLoadTemp = IntPtr.Zero; this.pSafeHandle = MIGetSafeHandle(); if (0 == this.pSafeHandle) { Console.Write(Client_Resource.Infrastructure_FailedToEncryptionAndDecryption); } iResult = MILoad(pLoadTemp, iLoadTemp, this.pSafeHandle); if (0 != iResult) { Console.Write(Client_Resource.Infrastructure_FailedToLoadKey); } } /// /// 修改加密密钥 /// /// 密钥 /// true if XXXX, false otherwise. public bool AlterKey(StringBuilder keyData) { int iResult = 0; iResult = MIAlterTransPwd(keyData, this.pSafeHandle); return iResult == 0; } /// /// 释放加密对象。 /// public void FreeHandle() { MIFreeSafeHandle(this.pSafeHandle); } /// /// 加密 /// /// 需加密的数据 /// 加密后的数据 /// 返回加密是否成功 public bool Encrypt(string szInStr, out string szOutStr) { byte[] szOutData = null; var szInData = Encoding.UTF8.GetBytes(szInStr); int iResult = 0; ////加密后的数据长度 int iOutEncryptDataLen = 0; bool iRev = false; ////待加密数据长度 int iInEncryptDataLen = szInData.Length; ////申请内存拷贝待加密数据 IntPtr pInEncryptData = System.Runtime.InteropServices.Marshal.AllocHGlobal(iInEncryptDataLen); System.Runtime.InteropServices.Marshal.Copy(szInData, 0, pInEncryptData, iInEncryptDataLen); ////获取加密后内存的长度 iResult = MIGetEncryptDataLen(ref iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen, this.pSafeHandle); if (0 == iResult) { ////创建内存 IntPtr pOutEncryptData = System.Runtime.InteropServices.Marshal.AllocHGlobal(iOutEncryptDataLen); ////加密 iResult = MITransEncrypt(pOutEncryptData, iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen, this.pSafeHandle); if (iResult == 0) { iRev = true; ////拷贝到数组上面 szOutData = new byte[iOutEncryptDataLen]; System.Runtime.InteropServices.Marshal.Copy(pOutEncryptData, szOutData, 0, iOutEncryptDataLen); } ////释放内存 System.Runtime.InteropServices.Marshal.FreeHGlobal(pOutEncryptData); } ////释放内存 System.Runtime.InteropServices.Marshal.FreeHGlobal(pInEncryptData); if (szOutData == null) { throw new MuchinfoException(ExceptionManager.EncryptError); } szOutStr = Convert.ToBase64String(szOutData); return iRev; } /// /// 解密 /// /// 需解密的数据 /// 解密后的数据 /// 返回解密是否成功 public bool Decrypt(byte[] szInData, ref byte[] szOutData) { bool iRev = false; int iResult = 0; ////解密后的数据长度 int iOutDecryptDataLen = 0; ////待解密数据长度 int iInDecryptDataLen = szInData.Length; ////申请内存拷贝待解密数据 IntPtr pInDecryptData = System.Runtime.InteropServices.Marshal.AllocHGlobal(iInDecryptDataLen); System.Runtime.InteropServices.Marshal.Copy(szInData, 0, pInDecryptData, iInDecryptDataLen); ////获取解密后内存的长度 iResult = MIGetDecryptDataLen(ref iOutDecryptDataLen, pInDecryptData, iInDecryptDataLen, this.pSafeHandle); if (0 == iResult) { ////创建内存 IntPtr pOutDecryptData = System.Runtime.InteropServices.Marshal.AllocHGlobal(iOutDecryptDataLen); ////加密 iResult = MITransDecrypt(pOutDecryptData, iOutDecryptDataLen, pInDecryptData, iInDecryptDataLen, this.pSafeHandle); if (iResult == 0) { iRev = true; ////拷贝到数组上面 szOutData = new byte[iOutDecryptDataLen]; System.Runtime.InteropServices.Marshal.Copy(pOutDecryptData, szOutData, 0, iOutDecryptDataLen); } ////释放内存 System.Runtime.InteropServices.Marshal.FreeHGlobal(pOutDecryptData); } ////释放内存 System.Runtime.InteropServices.Marshal.FreeHGlobal(pInDecryptData); return iRev; } /// /// 解密 /// /// /// public string AesDecrypt(string source) { byte[] szOutData = null; var szInData = Hex_16To2(source); //Convert.FromBase64String(source); // Encoding.UTF8.GetBytes(source); int iResult = 0; ////加密后的数据长度 int iOutEncryptDataLen = 0; ////待加密数据长度 int iInEncryptDataLen = szInData.Length; //获取加密句柄 //long pSafeHandle = MIGetSafeHandle(); ////申请内存拷贝待加密数据 IntPtr pInEncryptData = Marshal.AllocHGlobal(iInEncryptDataLen); Marshal.Copy(szInData, 0, pInEncryptData, iInEncryptDataLen); // 获取加密后内存的长度 iResult = MIGetDecryptDataLen(ref iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen, pSafeHandle); if (0 == iResult) { ////创建内存 IntPtr pOutEncryptData = Marshal.AllocHGlobal(iOutEncryptDataLen); ////加密 iResult = MITransDecrypt(pOutEncryptData, iOutEncryptDataLen, pInEncryptData, iInEncryptDataLen, pSafeHandle); if (iResult == 0) { ////拷贝到数组上面 szOutData = new byte[iOutEncryptDataLen]; Marshal.Copy(pOutEncryptData, szOutData, 0, iOutEncryptDataLen); } ////释放内存 Marshal.FreeHGlobal(pOutEncryptData); } ////释放内存 Marshal.FreeHGlobal(pInEncryptData); if (szOutData == null) { return null; } return Encoding.UTF8.GetString(szOutData); // return Encoding.UTF8.GetString(szOutData, 0, 64); } /// /// 16进制转2进制 /// public Byte[] Hex_16To2(String hexString) { if ((hexString.Length % 2) != 0) { hexString += " "; } Byte[] returnBytes = new Byte[hexString.Length / 2]; for (Int32 i = 0; i < returnBytes.Length; i++) { returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } return returnBytes; } /// /// 2进制转16进制 /// public String Hex_2To16(Byte[] bytes) { String hexString = String.Empty; Int32 iLength = 65535; if (bytes != null) { StringBuilder strB = new StringBuilder(); if (bytes.Length < iLength) { iLength = bytes.Length; } for (int i = 0; i < iLength; i++) { strB.Append(bytes[i].ToString("x2")); } hexString = strB.ToString(); } return hexString; } /// /// 加密密码 /// /// The secret key. /// The bank password. /// System.String. /// public string EncryptPassd(string secretKey, string bankPassword) { string encryptPass = string.Empty; var keyByte = Convert.FromBase64String(secretKey); byte[] decryptKey = null; ////使用本地密钥解密密钥 this.Decrypt(keyByte, ref decryptKey); string bitStr = Encoding.UTF8.GetString(decryptKey); var sb = new StringBuilder(bitStr); ////修改密钥 if (this.AlterKey(sb)) { this.Encrypt(bankPassword, out encryptPass); this.FreeHandle(); } else { throw new MuchinfoException(ExceptionManager.AlterKeyError); } return encryptPass; } } }