近来由于项目原因需要用到其他研发部门提供的VC写的OCX控件,主要功能为base64加解密后进行3DES运算,
网上从PUDN、CSDN都找了一些算法都不行,加密模式为CBC,密钥为24位、IV向量为8位。因为要从VC将这些
抠出来然后用到C#里然后与JAVA开发的服务端进行联调,由于调用、匹配、编码的问题折腾了好久,倒是学会了用
VC调试OCX,同时发现C#在非winform情况下调用VC写的OCX有些问题,现一一叙述。
1、如何用VC调试OCX
打开工程->Build->Excute->TSTCon32.exe(ctrl+F5)->Insert Control->选择你自己注册的控件->OK ->Control->Invoke Methods->将接口函数的参数值依次输入进去执行即可
2、C#在非winform情况下调用VC控件出现的问题
(1) 灾难性故障
未处理 System.Runtime.InteropServices.COMException
Message="灾难性故障 (异常来自 HRESULT:0x8000FFFF (E_UNEXPECTED))"
Source="mscorlib"
ErrorCode=-2147418113
解决办法:
使用aximp(ActiveX控件导入程序),将 ActiveX 控件的 COM 类型库中的类型定义转换为 Windows 窗体控件。
具体操作:在开始菜单VS2008选项里将命令行打开,aximp 路径:\ABC.ocx
(注意看DOS下的提示,有生成的目录及文件)
将生成的两个文件加载到工程中调用即可解决此问题,但加载完后我又遇到“无法调用此方法”的问题,因为我是在C#里的一个DLL中调用VC的OCX,
所以此问题的解决方法是:在DLL中增加个winform,将OCX中的方法在winform里重新包一层,然后在DLL中调用。
3、3Des加解密
/// <summary>
/// 3DES 加密(ECB模式)
/// </summary>
/// <param name="data">要加密字符串</param>
/// <param name="encryptbyte">加密后的数组</param>
/// <returns></returns>
public static bool EncryptData(byte[] data, ref byte[] encryptbyte)
{
try
{
string strkey = "111111111234567890123456";
byte[] keybyte = Encoding.UTF8.GetBytes(strkey);//最终密钥数组
MemoryStream mStream = new MemoryStream();
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.CBC;//选择加密模式
tdsp.Padding = PaddingMode.None;//选择填充字符模式
string ivstr = "12345678";
byte[] iv = Encoding.UTF8.GetBytes(ivstr);
CryptoStream cStream = new CryptoStream(mStream, tdsp.CreateEncryptor(keybyte, iv), CryptoStreamMode.Write);
cStream.Write(data, 0, data.Length);
cStream.FlushFinalBlock();
encryptbyte = mStream.ToArray();
cStream.Close();
mStream.Close();
}
catch (CryptographicException e)
{
ErrorMsg = "加密失败:"+e.Message;
return false;
}
return true;
}
/// <summary>
/// 3DES 解密(ECB模式)
/// </summary>
/// <param name="encrypdata">IN 加密的数据</param>
/// <param name="data">OUT 解密后的数据</param>
/// <returns></returns>
public static bool DecodeData(byte[] encrypdata, ref byte[] data)
{
try
{
string strkey = "111111111234567890123456";
byte[] keybyte = Encoding.UTF8.GetBytes(strkey);//最终密钥数组
MemoryStream msDecrypt = new MemoryStream(encrypdata);
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.CBC;
tdsp.Padding = PaddingMode.None;
string ivstr = "12345678";
byte[] iv = Encoding.UTF8.GetBytes(ivstr);
CryptoStream csDecrypt = new CryptoStream(msDecrypt,
tdsp.CreateDecryptor(keybyte, iv),
CryptoStreamMode.Read);
byte[] fromEncrypt = new byte[encrypdata.Length];
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
data = fromEncrypt;
msDecrypt.Close();
csDecrypt.Close();
return true;
}
catch (CryptographicException e)
{
ErrorMsg = "解密失败:" + e.Message;
return false;
}
}