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