1. 背景:

近期,由于工作上与第三方公司传输数据的时候需要采取数据加密,但是我们采用的时较低版本的Delphi 6;由于加密算法等差异,导致在传输的加密数据第三方一致解析不了(具体问题表现为base64加密中文乱码,AES加密方式的运算模式Mode,填充模式padding);限于代码的管理规范不能使用加密的插件,且网上搜索相关的delphi加密资料少之又少;故决定采取Visual Studio来写加密解密算法的动态库,由Delphi调用。

2. 行动:

(1)C#端的代码实现,首先在vs中创建一个“类库”项目TestDll:

using System.Runtime.InteropServices;
namespace TestDll
{public interface ITestClass{void YourProcedure(stirng param1);}[ClassInterface(ClassInterfaceType.None)]public classTestClass:ITestClass{public void YourProcedure(stirng param1);{   //自己的代码    }}
}

(2)C#端的配置实现:
a.选中该项目右击,选择【属性】,然后在【应用程序】中选择【程序集信息】如图:

b.同样是选中该项目右击,选择【属性】,然后在【生成】中选择【为COM互操作注册】保存,如图:

c.接下来是dll的注册,可以采用cmd命令框,也可以采用Bat文件:


(3)接下来是Delphi端的实现,Delphi程序调用此Dll方式有两种:
a.打开vs自带的工具“Visual Studio命令提示”,输入 TlbExp 路径\TestClass.dll 得到一个TestClass.tlb 文件(这个文件其实在编译的时候就会生成,可不做)。打开Delphi,选择“Project”–“import type library”找到刚才的TestClass.tlb,点击 CreateUnit,向delphi中引入一个com接口。
delphi 调用代码如下:

var aClass:TestClass;
beginaClass := CoTestClass.Create;aClass.YourProcedure('参数');
end;

b.不需生成tlb文件,仿照调用Excel的方式。代码如下:

var aClass: Variant;
beginaClass:= CreateOleObject('TestDll.TestClass');aClass.YourProcedure('参数');
end;

以上两种方法都可以调用成功,其中调用regasm.exe向系统注册dll是必需的。第一种方法需要生成tlb文件,并引入delphi中,操作繁琐,但可以看到接口的定义。第二种方法操作简单,但看不到接口的定义。


AES加解密code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;namespace Encryption
{public interface IAES{string AesEncrypt(string value, string key, int mode, int paddingMode, string iv = "");string AesDecrypt(string value, string key, int mode, int paddingMode, string iv = "");}[ClassInterface(ClassInterfaceType.None)]public class AES : IAES{/// <summary>/// AES加密/// </summary>/// <param name="value">待加密的字符串</param>/// <param name="key">秘钥(16,24,32位)</param>/// <param name="mode">运算模式(CBC = 1,ECB = 2,OFB = 3,CFB = 4,CTS = 5)</param>/// <param name="paddingMode">填充模式(None = 1,PKCS7 = 2,Zeros = 3,ANSIX923 = 4,ISO10126 = 5)/// <param name="iv">初始化向量(至少16位)</param>/// <returns>加密后的字符串</returns>public string AesEncrypt(string value, string key, int mode, int paddingMode, string iv = ""){if (string.IsNullOrEmpty(value)) return string.Empty;if (key == null) throw new Exception("未将对象引用设置到对象的实例。");if (key.Length < 16) throw new Exception("指定的密钥长度不能少于16位。");if (key.Length > 32) throw new Exception("指定的密钥长度不能多于32位。");if (key.Length != 16 && key.Length != 24 && key.Length != 32) throw new Exception("指定的密钥长度不明确。");if (!string.IsNullOrEmpty(iv)){if (iv.Length < 16) throw new Exception("指定的向量长度不能少于16位。");}var _keyByte = Encoding.UTF8.GetBytes(key);var _valueByte = Encoding.UTF8.GetBytes(value);using (var aes = new RijndaelManaged()){aes.IV = !string.IsNullOrEmpty(iv) ? Encoding.UTF8.GetBytes(iv) : Encoding.UTF8.GetBytes(key.Substring(0, 16));aes.Key = _keyByte;switch(mode) {case 1:aes.Mode = CipherMode.CBC;break;case 2:aes.Mode = CipherMode.ECB;break;case 3:aes.Mode = CipherMode.OFB;break;case 4:aes.Mode = CipherMode.CFB;break;case 5:aes.Mode = CipherMode.CTS;break;default:aes.Mode = CipherMode.CBC;break;}switch (paddingMode){case 1:aes.Padding = PaddingMode.None;break;case 2:aes.Padding = PaddingMode.PKCS7;break;case 3:aes.Padding = PaddingMode.Zeros;break;case 4:aes.Padding = PaddingMode.ANSIX923;break;case 5:aes.Padding = PaddingMode.ISO10126;break;default:aes.Padding = PaddingMode.PKCS7;break;}               var cryptoTransform = aes.CreateEncryptor();var resultArray = cryptoTransform.TransformFinalBlock(_valueByte, 0, _valueByte.Length);return Convert.ToBase64String(resultArray, 0, resultArray.Length);}}/// <summary>/// AES解密/// </summary>/// <param name="value">待解密的字符串</param>/// <param name="key">秘钥(16,24,32位)</param>/// <param name="mode">运算模式(CBC = 1,ECB = 2,OFB = 3,CFB = 4,CTS = 5)</param>/// <param name="paddingMode">填充模式(None = 1,PKCS7 = 2,Zeros = 3,ANSIX923 = 4,ISO10126 = 5)/// <param name="iv">初始化向量(至少16位)</param>/// <returns>解密后的字符串</returns>public string AesDecrypt(string value, string key, int mode, int paddingMode, string iv = ""){if (string.IsNullOrEmpty(value)) return string.Empty;if (key == null) throw new Exception("未将对象引用设置到对象的实例。");if (key.Length < 16) throw new Exception("指定的密钥长度不能少于16位。");if (key.Length > 32) throw new Exception("指定的密钥长度不能多于32位。");if (key.Length != 16 && key.Length != 24 && key.Length != 32) throw new Exception("指定的密钥长度不明确。");if (!string.IsNullOrEmpty(iv)){if (iv.Length < 16) throw new Exception("指定的向量长度不能少于16位。");}var _keyByte = Encoding.UTF8.GetBytes(key);var _valueByte = Convert.FromBase64String(value);using (var aes = new RijndaelManaged()){aes.IV = !string.IsNullOrEmpty(iv) ? Encoding.UTF8.GetBytes(iv) : Encoding.UTF8.GetBytes(key.Substring(0, 16));aes.Key = _keyByte;switch (mode){case 1:aes.Mode = CipherMode.CBC;break;case 2:aes.Mode = CipherMode.ECB;break;case 3:aes.Mode = CipherMode.OFB;break;case 4:aes.Mode = CipherMode.CFB;break;case 5:aes.Mode = CipherMode.CTS;break;default:aes.Mode = CipherMode.CBC;break;}switch (paddingMode){case 1:aes.Padding = PaddingMode.None;break;case 2:aes.Padding = PaddingMode.PKCS7;break;case 3:aes.Padding = PaddingMode.Zeros;break;case 4:aes.Padding = PaddingMode.ANSIX923;break;case 5:aes.Padding = PaddingMode.ISO10126;break;default:aes.Padding = PaddingMode.PKCS7;break;} var cryptoTransform = aes.CreateDecryptor();var resultArray = cryptoTransform.TransformFinalBlock(_valueByte, 0, _valueByte.Length);return Encoding.UTF8.GetString(resultArray);}}}
}

Base64加解密code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace Encryption
{public interface IBase64{string UnBase64String(string value);string ToBase64String(string value);}[ClassInterface(ClassInterfaceType.None)]public class Base64 : IBase64{   public  string UnBase64String(string value){if (value == null || value == ""){return "";}byte[] bytes = Convert.FromBase64String(value);return Encoding.UTF8.GetString(bytes);}public  string ToBase64String(string value){if (value == null || value == ""){return "";}byte[] bytes = Encoding.UTF8.GetBytes(value);return Convert.ToBase64String(bytes);}}
}

DES加解密code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;namespace Encryption
{interface IDES{string Encrypt(string entryStr, string key, int mode, int paddingMode);string Decrypt(string entryStr, string key, int mode, int paddingMode);}public class DES:IDES{/// <summary>/// DES 加密/// </summary>/// <param name="entryStr">待加密字符串</param>/// <param name="key">8位16进制密钥字符串</param>/// <param name="mode">运算模式(CBC = 1,ECB = 2,OFB = 3,CFB = 4,CTS = 5)</param>/// <param name="paddingMode">填充模式(None = 1,PKCS7 = 2,Zeros = 3,ANSIX923 = 4,ISO10126 = 5)/// <returns></returns>public string Encrypt(string entryStr, string key, int mode, int paddingMode){DESCryptoServiceProvider des = new DESCryptoServiceProvider();     switch (mode){case 1:des.Mode = CipherMode.CBC;break;case 2:des.Mode = CipherMode.ECB;break;case 3:des.Mode = CipherMode.OFB;break;case 4:des.Mode = CipherMode.CFB;break;case 5:des.Mode = CipherMode.CTS;break;default:des.Mode = CipherMode.ECB;break;}switch (paddingMode){case 1:des.Padding = PaddingMode.None;break;case 2:des.Padding = PaddingMode.PKCS7;break;case 3:des.Padding = PaddingMode.Zeros;break;case 4:des.Padding = PaddingMode.ANSIX923;break;case 5:des.Padding = PaddingMode.ISO10126;break;default:des.Padding = PaddingMode.Zeros;break;}var _keyByte = Encoding.UTF8.GetBytes(key);var _valueByte = Encoding.UTF8.GetBytes(entryStr);des.Key = _keyByte;using (MemoryStream ms = new MemoryStream()){byte[] bytes = _valueByte;using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)){cs.Write(bytes, 0, bytes.Count());cs.FlushFinalBlock();}return System.Text.Encoding.Default.GetString(ms.ToArray()); }}/// <summary>/// DES 解密 /// </summary>/// <param name="bytes">待解密加密的字符串</param>/// <param name="key">8位16进制密钥字符串</param>/// <param name="mode">运算模式(CBC = 1,ECB = 2,OFB = 3,CFB = 4,CTS = 5)</param>/// <param name="paddingMode">填充模式(None = 1,PKCS7 = 2,Zeros = 3,ANSIX923 = 4,ISO10126 = 5)/// <returns></returns>public string Decrypt(string entryStr, string key, int mode, int paddingMode){DESCryptoServiceProvider des = new DESCryptoServiceProvider();switch (mode){case 1:des.Mode = CipherMode.CBC;break;case 2:des.Mode = CipherMode.ECB;break;case 3:des.Mode = CipherMode.OFB;break;case 4:des.Mode = CipherMode.CFB;break;case 5:des.Mode = CipherMode.CTS;break;default:des.Mode = CipherMode.ECB;break;}switch (paddingMode){case 1:des.Padding = PaddingMode.None;break;case 2:des.Padding = PaddingMode.PKCS7;break;case 3:des.Padding = PaddingMode.Zeros;break;case 4:des.Padding = PaddingMode.ANSIX923;break;case 5:des.Padding = PaddingMode.ISO10126;break;default:des.Padding = PaddingMode.Zeros;break;}var _keyByte = Encoding.UTF8.GetBytes(key);var _valueByte = Encoding.UTF8.GetBytes(entryStr);des.Key = _keyByte;using (MemoryStream ms = new MemoryStream()){using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write)){cs.Write(_valueByte, 0, _valueByte.Count());cs.FlushFinalBlock();}return System.Text.Encoding.Default.GetString(ms.ToArray()); }}}
}

MD5加密code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;namespace Encryption
{interface IMD5Encryt{string GetMd5Str(string ConvertString);string UserMd5(string str);}class MD5Encryt : IMD5Encryt{/// <summary>/// MD5 16位加密/// </summary>/// <param name="ConvertString"></param>/// <returns></returns>public string GetMd5Str(string ConvertString){MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);t2 = t2.Replace("-", "");return t2;}/// <summary>/// MD5 32位加密/// </summary>/// <param name="str"></param>/// <returns></returns>public string UserMd5(string str){string cl = str;string pwd = "";MD5 md5 = MD5.Create();//实例化一个md5对像// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择 byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得for (int i = 0; i < s.Length; i++){// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符 pwd = pwd + s[i].ToString("X");}return pwd;}}
}

3. 测试:

(1)Delphi端调用C#的base64加密:

(2)Delphi端调用C#的base64解密:

4.报错与解决

(1)按照配置生成了,也regasm注册成功了,但是在调用的时候会报错:

原因:虽然说我们用命令行注册时提示成功,但是我们所进入的Framework有问题,如图Microsoft.NET文件夹下面有两个版本的Framework,请选择和自己计算机位数相同的版本,或者说可以逐个尝试一下。

另外:选择regasm所在的目录也要根据vs输出的Framework版本一致,例如我的是4.5,那么需要进入v4.0.30319:

输出的目标框架在属性中可以看到:

5.感谢:

感谢您看到了这儿,请收下测试通过的源码(包含Base64/AES/DES的加密解密(可指定运算模式Mode,填充模式Padding,向量V),MD5的加密):
链接:https://pan.baidu.com/s/1CLnwtGOFf0oGzCvyNef0YA 密码:hyuj

Delphi调用C#的加密解密(Base64/AES/DES/MD5可扩充)相关推荐

  1. DES加密解密与AES加密解密

    × 目录 [1]AES加密算法和DES加密算法的效率比较 [2]AES和DES加密解密代码 随着开发时间的变长,当初认为比较难的东西,现在渐渐也就变的不那么难了!特别对于一些经常很少使用的类,时间长了 ...

  2. (三)Kotlin加密/解密之AES和DES

    Kotlin加密/解密系列 (一)Kotlin加密/解密之ASCII码 (二)Kotlin加密/解密之凯撒加密算法 文章目录 Kotlin加密/解密系列 前言 一.加密算法 二.Base64编码 1. ...

  3. 【Kotlin】加密解密2:DES、AES加密和解密

    文章目录 Api文档 DES加密解密 Base64加密和解密 AES加密解密 DES和AES密钥长度 工作模式和填充模式 对称加密的应用场景 Api文档 https://docs.oracle.com ...

  4. python 加密解密 rc4_python实现rc4加密解密,base64输出

    这里将告诉您python实现rc4加密解密,base64输出,具体实现方法:from Crypto.Cipher import ARC4 as rc4cipher import base64 def ...

  5. asp php base64 加密解密,base64加密解密_php base64_decode 解码方法

    base64加密解密_php base64_decode 解码方法 观点1: php实现base64加密解密 在PHP中我们可以直接使用PHP自带的函数 base64_encode() 和 base6 ...

  6. java aes128加密解密_java AES 128 位加密解密算法

    最近在做app后台的服务器,使用到AES加密解密算法,无奈网上的都不符合要求,于是自己借鉴着写了一个AES加密解密工具. 密钥长度问题 默认 Java 中仅支持 128 位密钥,当使用 256 位密钥 ...

  7. java php aes加密解密_php aes 加密解密可与java对接

    php aes 加密解密可与java对接 博主:liu1693 发表时间:2017-02-23 16:52:27 浏览量:100 class Encrypt{ //加密方法 public static ...

  8. .Net(c#)加密解密之Aes和Des

    /// <summary> /// .Net加密解密帮助类 /// </summary> public class NetCryptoHelper { #region des实 ...

  9. php mcrypt aes,简单的PHP加密/解密(Mcrypt,AES)

    我正在寻找使用Mcrypt的简单但加密强大的AES实现AES. 希望将其归结为一对简单的函数,$garble = encrypt($key,$payload)和$payload = decrypt($ ...

最新文章

  1. [译]Front-end-Developer-Interview-Questions
  2. 独立开发者分享:游戏本地化的6个建议
  3. Unity3D学习笔记之五为Prefab添加材质
  4. JavaScript内置对象Date常用函数
  5. 关于头文件中的 static inline函数
  6. python偶数个数_python基础
  7. 飞秋2010下载又用什么样的技术
  8. html 进度条roll,js实现增加数字显示的环形进度条效果
  9. 换SSD硬盘,重装系统,一阵子忙乱
  10. App Store中国区下架近5万款未提供版号的游戏;微软源代码遭黑客访问;Rust 1.49.0发布
  11. linux python守护进程编写
  12. h5聊天页面 jquery_基于Jquery WeUI的微信开发H5页面控件的经验总结(1)
  13. 麦当劳将携手逾100所职业院校提升就业能力;百胜中国一季度开设315家新店 | 美通企业日报
  14. TcaplusDB X 光与夜之恋,来谈一场高沉浸式的恋爱吧
  15. Unity 跳转第三方App
  16. 2. Python函数式编程中的字符串,元组,函数的分类,高阶函数,一篇文章都介绍一遍
  17. 接口测试必知必会知识点
  18. 颜色恒常知觉的计算理论——Retinex理论
  19. The Elegant Manjaro——ManjaroLinux配置与美化教程
  20. poj 1383 Labyrinth

热门文章

  1. spring jpa mysql集群_微框架:Springboot+Jpa+mysql零基础上手班
  2. 嵌入式电路设计(物联网esp32最小电路设计)
  3. linux系统 安卓系统安装教程,Linux系统下安装android sdk的方法步骤
  4. 响应服务器535 5.7.1 unab,带有Gmail的JavaMail:535-5.7.1不接受用户名和密码
  5. java 判断文件是否打开过_【后端开发】Java中如何判断文件是否被隐藏?(代码示例)...
  6. oracle 函数 实现重载_Oracle 过程、函数、包、重载、自主事务
  7. vba显示正在加载_利用VBA代码显示工作簿的路径及完全路径的方案及对工作薄的操作...
  8. mysql hash切分_轻松优化MySQL-之数据库切分1
  9. pdu报头内容_1OSI七层参考模型,各个报头内容
  10. 获取计算机主机mac地址的命令有,怎么获取计算机的MAC地址和IP地址?